]> Git Repo - u-boot.git/blob - drivers/pinctrl/rockchip/pinctrl-rockchip-core.c
Subtree merge tag 'v6.8-dts' of devicetree-rebasing repo [1] into dts/upstream
[u-boot.git] / drivers / pinctrl / rockchip / pinctrl-rockchip-core.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2019 Rockchip Electronics Co., Ltd
4  */
5
6 #include <common.h>
7 #include <dm.h>
8 #include <log.h>
9 #include <dm/pinctrl.h>
10 #include <regmap.h>
11 #include <syscon.h>
12 #include <fdtdec.h>
13 #include <linux/bitops.h>
14 #include <linux/libfdt.h>
15
16 #include "pinctrl-rockchip.h"
17
18 #define MAX_ROCKCHIP_PINS_ENTRIES       30
19 #define MAX_ROCKCHIP_GPIO_PER_BANK      32
20 #define RK_FUNC_GPIO                    0
21
22 static int rockchip_verify_config(struct udevice *dev, u32 bank, u32 pin)
23 {
24         struct rockchip_pinctrl_priv *priv = dev_get_priv(dev);
25         struct rockchip_pin_ctrl *ctrl = priv->ctrl;
26
27         if (bank >= ctrl->nr_banks) {
28                 debug("pin conf bank %d >= nbanks %d\n", bank, ctrl->nr_banks);
29                 return -EINVAL;
30         }
31
32         if (pin >= MAX_ROCKCHIP_GPIO_PER_BANK) {
33                 debug("pin conf pin %d >= %d\n", pin,
34                       MAX_ROCKCHIP_GPIO_PER_BANK);
35                 return -EINVAL;
36         }
37
38         return 0;
39 }
40
41 void rockchip_get_recalced_mux(struct rockchip_pin_bank *bank, int pin,
42                                int *reg, u8 *bit, int *mask)
43 {
44         struct rockchip_pinctrl_priv *priv = bank->priv;
45         struct rockchip_pin_ctrl *ctrl = priv->ctrl;
46         struct rockchip_mux_recalced_data *data;
47         int i;
48
49         for (i = 0; i < ctrl->niomux_recalced; i++) {
50                 data = &ctrl->iomux_recalced[i];
51                 if (data->num == bank->bank_num &&
52                     data->pin == pin)
53                         break;
54         }
55
56         if (i >= ctrl->niomux_recalced)
57                 return;
58
59         *reg = data->reg;
60         *mask = data->mask;
61         *bit = data->bit;
62 }
63
64 static enum rockchip_pin_route_type
65 rockchip_get_mux_route(struct rockchip_pin_bank *bank, int pin,
66                        int mux, u32 *reg, u32 *value)
67 {
68         struct rockchip_pinctrl_priv *priv = bank->priv;
69         struct rockchip_pin_ctrl *ctrl = priv->ctrl;
70         struct rockchip_mux_route_data *data;
71         int i;
72
73         for (i = 0; i < ctrl->niomux_routes; i++) {
74                 data = &ctrl->iomux_routes[i];
75                 if (data->bank_num == bank->bank_num &&
76                     data->pin == pin && data->func == mux)
77                         break;
78         }
79
80         if (i >= ctrl->niomux_routes)
81                 return ROUTE_TYPE_INVALID;
82
83         *reg = data->route_offset;
84         *value = data->route_val;
85
86         return data->route_type;
87 }
88
89 int rockchip_get_mux_data(int mux_type, int pin, u8 *bit, int *mask)
90 {
91         int offset = 0;
92
93         if (mux_type & IOMUX_WIDTH_4BIT) {
94                 if ((pin % 8) >= 4)
95                         offset = 0x4;
96                 *bit = (pin % 4) * 4;
97                 *mask = 0xf;
98         } else if (mux_type & IOMUX_WIDTH_3BIT) {
99                 /*
100                  * pin0 ~ pin4 are at first register, and
101                  * pin5 ~ pin7 are at second register.
102                  */
103                 if ((pin % 8) >= 5)
104                         offset = 0x4;
105                 *bit = (pin % 8 % 5) * 3;
106                 *mask = 0x7;
107         } else {
108                 *bit = (pin % 8) * 2;
109                 *mask = 0x3;
110         }
111
112         return offset;
113 }
114
115 static int rockchip_get_mux(struct rockchip_pin_bank *bank, int pin)
116 {
117         struct rockchip_pinctrl_priv *priv = bank->priv;
118         int iomux_num = (pin / 8);
119         struct regmap *regmap;
120         unsigned int val;
121         int reg, ret, mask, mux_type;
122         u8 bit;
123
124         if (iomux_num > 3)
125                 return -EINVAL;
126
127         if (bank->iomux[iomux_num].type & IOMUX_UNROUTED) {
128                 debug("pin %d is unrouted\n", pin);
129                 return -EINVAL;
130         }
131
132         if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY)
133                 return RK_FUNC_GPIO;
134
135         regmap = (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
136                                 ? priv->regmap_pmu : priv->regmap_base;
137
138         /* get basic quadrupel of mux registers and the correct reg inside */
139         mux_type = bank->iomux[iomux_num].type;
140         reg = bank->iomux[iomux_num].offset;
141         reg += rockchip_get_mux_data(mux_type, pin, &bit, &mask);
142
143         if (bank->recalced_mask & BIT(pin))
144                 rockchip_get_recalced_mux(bank, pin, &reg, &bit, &mask);
145
146         ret = regmap_read(regmap, reg, &val);
147         if (ret)
148                 return ret;
149
150         return ((val >> bit) & mask);
151 }
152
153 static int rockchip_pinctrl_get_gpio_mux(struct udevice *dev, int banknum,
154                                          int index)
155 {       struct rockchip_pinctrl_priv *priv = dev_get_priv(dev);
156         struct rockchip_pin_ctrl *ctrl = priv->ctrl;
157
158         return rockchip_get_mux(&ctrl->pin_banks[banknum], index);
159 }
160
161 static int rockchip_verify_mux(struct rockchip_pin_bank *bank,
162                                int pin, int mux)
163 {
164         int iomux_num = (pin / 8);
165
166         if (iomux_num > 3)
167                 return -EINVAL;
168
169         if (bank->iomux[iomux_num].type & IOMUX_UNROUTED) {
170                 debug("pin %d is unrouted\n", pin);
171                 return -EINVAL;
172         }
173
174         if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY) {
175                 if (mux != IOMUX_GPIO_ONLY) {
176                         debug("pin %d only supports a gpio mux\n", pin);
177                         return -ENOTSUPP;
178                 }
179         }
180
181         return 0;
182 }
183
184 /*
185  * Set a new mux function for a pin.
186  *
187  * The register is divided into the upper and lower 16 bit. When changing
188  * a value, the previous register value is not read and changed. Instead
189  * it seems the changed bits are marked in the upper 16 bit, while the
190  * changed value gets set in the same offset in the lower 16 bit.
191  * All pin settings seem to be 2 bit wide in both the upper and lower
192  * parts.
193  * @bank: pin bank to change
194  * @pin: pin to change
195  * @mux: new mux function to set
196  */
197 static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
198 {
199         struct rockchip_pinctrl_priv *priv = bank->priv;
200         struct rockchip_pin_ctrl *ctrl = priv->ctrl;
201         int iomux_num = (pin / 8);
202         int ret;
203
204         ret = rockchip_verify_mux(bank, pin, mux);
205         if (ret < 0)
206                 return ret;
207
208         if (bank->iomux[iomux_num].type & IOMUX_GPIO_ONLY)
209                 return 0;
210
211         debug("setting mux of GPIO%d-%d to %d\n", bank->bank_num, pin, mux);
212
213         if (!ctrl->set_mux)
214                 return -ENOTSUPP;
215
216         ret = ctrl->set_mux(bank, pin, mux);
217         if (ret)
218                 return ret;
219
220         if (bank->route_mask & BIT(pin)) {
221                 struct regmap *regmap;
222                 u32 route_reg = 0, route_val = 0;
223
224                 ret = rockchip_get_mux_route(bank, pin, mux,
225                                              &route_reg, &route_val);
226                 switch (ret) {
227                 case ROUTE_TYPE_DEFAULT:
228                         if (bank->iomux[iomux_num].type & IOMUX_SOURCE_PMU)
229                                 regmap = priv->regmap_pmu;
230                         else if (bank->iomux[iomux_num].type & IOMUX_L_SOURCE_PMU)
231                                 regmap = (pin % 8 < 4) ? priv->regmap_pmu : priv->regmap_base;
232                         else
233                                 regmap = priv->regmap_base;
234
235                         regmap_write(regmap, route_reg, route_val);
236                         break;
237                 case ROUTE_TYPE_TOPGRF:
238                         regmap_write(priv->regmap_base, route_reg, route_val);
239                         break;
240                 case ROUTE_TYPE_PMUGRF:
241                         regmap_write(priv->regmap_pmu, route_reg, route_val);
242                         break;
243                 case ROUTE_TYPE_INVALID:
244                         fallthrough;
245                 default:
246                         break;
247                 }
248         }
249
250         return 0;
251 }
252
253 static int rockchip_perpin_drv_list[DRV_TYPE_MAX][8] = {
254         { 2, 4, 8, 12, -1, -1, -1, -1 },
255         { 3, 6, 9, 12, -1, -1, -1, -1 },
256         { 5, 10, 15, 20, -1, -1, -1, -1 },
257         { 4, 6, 8, 10, 12, 14, 16, 18 },
258         { 4, 7, 10, 13, 16, 19, 22, 26 }
259 };
260
261 int rockchip_translate_drive_value(int type, int strength)
262 {
263         int i, ret;
264
265         ret = -EINVAL;
266         for (i = 0; i < ARRAY_SIZE(rockchip_perpin_drv_list[type]); i++) {
267                 if (rockchip_perpin_drv_list[type][i] == strength) {
268                         ret = i;
269                         break;
270                 } else if (rockchip_perpin_drv_list[type][i] < 0) {
271                         ret = rockchip_perpin_drv_list[type][i];
272                         break;
273                 }
274         }
275
276         return ret;
277 }
278
279 static int rockchip_set_drive_perpin(struct rockchip_pin_bank *bank,
280                                      int pin_num, int strength)
281 {
282         struct rockchip_pinctrl_priv *priv = bank->priv;
283         struct rockchip_pin_ctrl *ctrl = priv->ctrl;
284
285         debug("setting drive of GPIO%d-%d to %d\n", bank->bank_num,
286               pin_num, strength);
287
288         if (!ctrl->set_drive)
289                 return -ENOTSUPP;
290
291         return ctrl->set_drive(bank, pin_num, strength);
292 }
293
294 static int rockchip_pull_list[PULL_TYPE_MAX][4] = {
295         {
296                 PIN_CONFIG_BIAS_DISABLE,
297                 PIN_CONFIG_BIAS_PULL_UP,
298                 PIN_CONFIG_BIAS_PULL_DOWN,
299                 PIN_CONFIG_BIAS_BUS_HOLD
300         },
301         {
302                 PIN_CONFIG_BIAS_DISABLE,
303                 PIN_CONFIG_BIAS_PULL_DOWN,
304                 PIN_CONFIG_BIAS_DISABLE,
305                 PIN_CONFIG_BIAS_PULL_UP
306         },
307 };
308
309 int rockchip_translate_pull_value(int type, int pull)
310 {
311         int i, ret;
312
313         ret = -EINVAL;
314         for (i = 0; i < ARRAY_SIZE(rockchip_pull_list[type]);
315                 i++) {
316                 if (rockchip_pull_list[type][i] == pull) {
317                         ret = i;
318                         break;
319                 }
320         }
321
322         return ret;
323 }
324
325 static int rockchip_set_pull(struct rockchip_pin_bank *bank,
326                              int pin_num, int pull)
327 {
328         struct rockchip_pinctrl_priv *priv = bank->priv;
329         struct rockchip_pin_ctrl *ctrl = priv->ctrl;
330
331         debug("setting pull of GPIO%d-%d to %d\n", bank->bank_num,
332               pin_num, pull);
333
334         if (!ctrl->set_pull)
335                 return -ENOTSUPP;
336
337         return ctrl->set_pull(bank, pin_num, pull);
338 }
339
340 static int rockchip_set_schmitt(struct rockchip_pin_bank *bank,
341                                 int pin_num, int enable)
342 {
343         struct rockchip_pinctrl_priv *priv = bank->priv;
344         struct rockchip_pin_ctrl *ctrl = priv->ctrl;
345
346         debug("setting input schmitt of GPIO%d-%d to %d\n", bank->bank_num,
347               pin_num, enable);
348
349         if (!ctrl->set_schmitt)
350                 return -ENOTSUPP;
351
352         return ctrl->set_schmitt(bank, pin_num, enable);
353 }
354
355 /* set the pin config settings for a specified pin */
356 static int rockchip_pinconf_set(struct rockchip_pin_bank *bank,
357                                 u32 pin, u32 param, u32 arg)
358 {
359         int rc;
360
361         switch (param) {
362         case PIN_CONFIG_BIAS_DISABLE:
363         case PIN_CONFIG_BIAS_PULL_UP:
364         case PIN_CONFIG_BIAS_PULL_DOWN:
365         case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
366         case PIN_CONFIG_BIAS_BUS_HOLD:
367                 rc = rockchip_set_pull(bank, pin, param);
368                 if (rc)
369                         return rc;
370                 break;
371
372         case PIN_CONFIG_DRIVE_STRENGTH:
373                 rc = rockchip_set_drive_perpin(bank, pin, arg);
374                 if (rc < 0)
375                         return rc;
376                 break;
377
378         case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
379                 rc = rockchip_set_schmitt(bank, pin, arg);
380                 if (rc < 0)
381                         return rc;
382                 break;
383
384         default:
385                 break;
386         }
387
388         return 0;
389 }
390
391 static const struct pinconf_param rockchip_conf_params[] = {
392         { "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 },
393         { "bias-bus-hold", PIN_CONFIG_BIAS_BUS_HOLD, 0 },
394         { "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 },
395         { "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 },
396         { "bias-pull-pin-default", PIN_CONFIG_BIAS_PULL_PIN_DEFAULT, 1 },
397         { "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 0 },
398         { "input-schmitt-disable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 0 },
399         { "input-schmitt-enable", PIN_CONFIG_INPUT_SCHMITT_ENABLE, 1 },
400 };
401
402 static int rockchip_pinconf_prop_name_to_param(const char *property,
403                                                u32 *default_value)
404 {
405         const struct pinconf_param *p, *end;
406
407         p = rockchip_conf_params;
408         end = p + sizeof(rockchip_conf_params) / sizeof(struct pinconf_param);
409
410         /* See if this pctldev supports this parameter */
411         for (; p < end; p++) {
412                 if (!strcmp(property, p->property)) {
413                         *default_value = p->default_value;
414                         return p->param;
415                 }
416         }
417
418         *default_value = 0;
419         return -EPERM;
420 }
421
422 static int rockchip_pinctrl_set_state(struct udevice *dev,
423                                       struct udevice *config)
424 {
425         struct rockchip_pinctrl_priv *priv = dev_get_priv(dev);
426         struct rockchip_pin_ctrl *ctrl = priv->ctrl;
427         u32 cells[MAX_ROCKCHIP_PINS_ENTRIES * 4];
428         u32 bank, pin, mux, conf, arg, default_val;
429         int ret, count, i;
430         const char *prop_name;
431         const void *value;
432         int prop_len, param;
433         const u32 *data;
434         ofnode node;
435         struct ofprop prop;
436         data = dev_read_prop(config, "rockchip,pins", &count);
437         if (count < 0) {
438                 debug("%s: bad array size %d\n", __func__, count);
439                 return -EINVAL;
440         }
441
442         count /= sizeof(u32);
443         if (count > MAX_ROCKCHIP_PINS_ENTRIES * 4) {
444                 debug("%s: unsupported pins array count %d\n",
445                       __func__, count);
446                 return -EINVAL;
447         }
448
449         for (i = 0; i < count; i++)
450                 cells[i] = fdt32_to_cpu(data[i]);
451
452         for (i = 0; i < (count >> 2); i++) {
453                 bank = cells[4 * i + 0];
454                 pin = cells[4 * i + 1];
455                 mux = cells[4 * i + 2];
456                 conf = cells[4 * i + 3];
457
458                 ret = rockchip_verify_config(dev, bank, pin);
459                 if (ret)
460                         return ret;
461
462                 ret = rockchip_set_mux(&ctrl->pin_banks[bank], pin, mux);
463                 if (ret)
464                         return ret;
465
466                 node = ofnode_get_by_phandle(conf);
467                 if (!ofnode_valid(node))
468                         return -ENODEV;
469                 ofnode_for_each_prop(prop, node) {
470                         value = ofprop_get_property(&prop, &prop_name, &prop_len);
471                         if (!value)
472                                 continue;
473
474                         param = rockchip_pinconf_prop_name_to_param(prop_name,
475                                                                     &default_val);
476                         if (param < 0)
477                                 continue;
478
479                         if (prop_len >= sizeof(fdt32_t))
480                                 arg = fdt32_to_cpu(*(fdt32_t *)value);
481                         else
482                                 arg = default_val;
483
484                         ret = rockchip_pinconf_set(&ctrl->pin_banks[bank], pin,
485                                                    param, arg);
486                         if (ret) {
487                                 debug("%s: rockchip_pinconf_set fail: %d\n",
488                                       __func__, ret);
489                                 return ret;
490                         }
491                 }
492         }
493
494         return 0;
495 }
496
497 const struct pinctrl_ops rockchip_pinctrl_ops = {
498         .set_state                      = rockchip_pinctrl_set_state,
499         .get_gpio_mux                   = rockchip_pinctrl_get_gpio_mux,
500 };
501
502 /* retrieve the soc specific data */
503 static struct rockchip_pin_ctrl *rockchip_pinctrl_get_soc_data(struct udevice *dev)
504 {
505         struct rockchip_pinctrl_priv *priv = dev_get_priv(dev);
506         struct rockchip_pin_ctrl *ctrl =
507                         (struct rockchip_pin_ctrl *)dev_get_driver_data(dev);
508         struct rockchip_pin_bank *bank;
509         int grf_offs, pmu_offs, drv_grf_offs, drv_pmu_offs, i, j;
510
511         grf_offs = ctrl->grf_mux_offset;
512         pmu_offs = ctrl->pmu_mux_offset;
513         drv_pmu_offs = ctrl->pmu_drv_offset;
514         drv_grf_offs = ctrl->grf_drv_offset;
515         bank = ctrl->pin_banks;
516
517         for (i = 0; i < ctrl->nr_banks; ++i, ++bank) {
518                 int bank_pins = 0;
519
520                 bank->priv = priv;
521                 bank->pin_base = ctrl->nr_pins;
522                 ctrl->nr_pins += bank->nr_pins;
523
524                 /* calculate iomux and drv offsets */
525                 for (j = 0; j < 4; j++) {
526                         struct rockchip_iomux *iom = &bank->iomux[j];
527                         struct rockchip_drv *drv = &bank->drv[j];
528                         int inc;
529
530                         if (bank_pins >= bank->nr_pins)
531                                 break;
532
533                         /* preset iomux offset value, set new start value */
534                         if (iom->offset >= 0) {
535                                 if (iom->type & IOMUX_SOURCE_PMU)
536                                         pmu_offs = iom->offset;
537                                 else
538                                         grf_offs = iom->offset;
539                         } else { /* set current iomux offset */
540                                 iom->offset = (iom->type & IOMUX_SOURCE_PMU) ?
541                                                         pmu_offs : grf_offs;
542                         }
543
544                         /* preset drv offset value, set new start value */
545                         if (drv->offset >= 0) {
546                                 if (iom->type & IOMUX_SOURCE_PMU)
547                                         drv_pmu_offs = drv->offset;
548                                 else
549                                         drv_grf_offs = drv->offset;
550                         } else { /* set current drv offset */
551                                 drv->offset = (iom->type & IOMUX_SOURCE_PMU) ?
552                                                 drv_pmu_offs : drv_grf_offs;
553                         }
554
555                         debug("bank %d, iomux %d has iom_offset 0x%x drv_offset 0x%x\n",
556                               i, j, iom->offset, drv->offset);
557
558                         /*
559                          * Increase offset according to iomux width.
560                          * 4bit iomux'es are spread over two registers.
561                          */
562                         inc = (iom->type & (IOMUX_WIDTH_4BIT |
563                                             IOMUX_WIDTH_3BIT |
564                                             IOMUX_8WIDTH_2BIT)) ? 8 : 4;
565                         if ((iom->type & IOMUX_SOURCE_PMU) || (iom->type & IOMUX_L_SOURCE_PMU))
566                                 pmu_offs += inc;
567                         else
568                                 grf_offs += inc;
569
570                         /*
571                          * Increase offset according to drv width.
572                          * 3bit drive-strenth'es are spread over two registers.
573                          */
574                         if ((drv->drv_type == DRV_TYPE_IO_1V8_3V0_AUTO) ||
575                             (drv->drv_type == DRV_TYPE_IO_3V3_ONLY))
576                                 inc = 8;
577                         else
578                                 inc = 4;
579
580                         if (iom->type & IOMUX_SOURCE_PMU)
581                                 drv_pmu_offs += inc;
582                         else
583                                 drv_grf_offs += inc;
584
585                         bank_pins += 8;
586                 }
587
588                 /* calculate the per-bank recalced_mask */
589                 for (j = 0; j < ctrl->niomux_recalced; j++) {
590                         int pin = 0;
591
592                         if (ctrl->iomux_recalced[j].num == bank->bank_num) {
593                                 pin = ctrl->iomux_recalced[j].pin;
594                                 bank->recalced_mask |= BIT(pin);
595                         }
596                 }
597
598                 /* calculate the per-bank route_mask */
599                 for (j = 0; j < ctrl->niomux_routes; j++) {
600                         int pin = 0;
601
602                         if (ctrl->iomux_routes[j].bank_num == bank->bank_num) {
603                                 pin = ctrl->iomux_routes[j].pin;
604                                 bank->route_mask |= BIT(pin);
605                         }
606                 }
607         }
608
609         return ctrl;
610 }
611
612 int rockchip_pinctrl_probe(struct udevice *dev)
613 {
614         struct rockchip_pinctrl_priv *priv = dev_get_priv(dev);
615         struct rockchip_pin_ctrl *ctrl;
616         struct udevice *syscon;
617         struct regmap *regmap;
618         int ret = 0;
619
620         /* get rockchip grf syscon phandle */
621         ret = uclass_get_device_by_phandle(UCLASS_SYSCON, dev, "rockchip,grf",
622                                            &syscon);
623         if (ret) {
624                 debug("unable to find rockchip,grf syscon device (%d)\n", ret);
625                 return ret;
626         }
627
628         /* get grf-reg base address */
629         regmap = syscon_get_regmap(syscon);
630         if (!regmap) {
631                 debug("unable to find rockchip grf regmap\n");
632                 return -ENODEV;
633         }
634         priv->regmap_base = regmap;
635
636         /* option: get pmu-reg base address */
637         ret = uclass_get_device_by_phandle(UCLASS_SYSCON, dev, "rockchip,pmu",
638                                            &syscon);
639         if (!ret) {
640                 /* get pmugrf-reg base address */
641                 regmap = syscon_get_regmap(syscon);
642                 if (!regmap) {
643                         debug("unable to find rockchip pmu regmap\n");
644                         return -ENODEV;
645                 }
646                 priv->regmap_pmu = regmap;
647         }
648
649         ctrl = rockchip_pinctrl_get_soc_data(dev);
650         if (!ctrl) {
651                 debug("driver data not available\n");
652                 return -EINVAL;
653         }
654
655         priv->ctrl = ctrl;
656         return 0;
657 }
This page took 0.067604 seconds and 4 git commands to generate.