GNU Linux-libre 6.9.1-gnu
[releases.git] / drivers / pinctrl / intel / pinctrl-tangier.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Intel Tangier pinctrl driver
4  *
5  * Copyright (C) 2016, 2023 Intel Corporation
6  *
7  * Authors: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
8  *          Raag Jadav <raag.jadav@intel.com>
9  */
10
11 #include <linux/bits.h>
12 #include <linux/cleanup.h>
13 #include <linux/device.h>
14 #include <linux/err.h>
15 #include <linux/errno.h>
16 #include <linux/export.h>
17 #include <linux/io.h>
18 #include <linux/module.h>
19 #include <linux/overflow.h>
20 #include <linux/platform_device.h>
21 #include <linux/property.h>
22 #include <linux/seq_file.h>
23 #include <linux/spinlock.h>
24 #include <linux/types.h>
25
26 #include <linux/pinctrl/pinconf-generic.h>
27 #include <linux/pinctrl/pinconf.h>
28 #include <linux/pinctrl/pinctrl.h>
29 #include <linux/pinctrl/pinmux.h>
30
31 #include "../core.h"
32 #include "pinctrl-intel.h"
33 #include "pinctrl-tangier.h"
34
35 #define SLEW_OFFSET                     0x000
36 #define BUFCFG_OFFSET                   0x100
37 #define MISC_OFFSET                     0x300
38
39 #define BUFCFG_PINMODE_SHIFT            0
40 #define BUFCFG_PINMODE_MASK             GENMASK(2, 0)
41 #define BUFCFG_PINMODE_GPIO             0
42 #define BUFCFG_PUPD_VAL_SHIFT           4
43 #define BUFCFG_PUPD_VAL_MASK            GENMASK(5, 4)
44 #define BUFCFG_PUPD_VAL_2K              0
45 #define BUFCFG_PUPD_VAL_20K             1
46 #define BUFCFG_PUPD_VAL_50K             2
47 #define BUFCFG_PUPD_VAL_910             3
48 #define BUFCFG_PU_EN                    BIT(8)
49 #define BUFCFG_PD_EN                    BIT(9)
50 #define BUFCFG_Px_EN_MASK               GENMASK(9, 8)
51 #define BUFCFG_SLEWSEL                  BIT(10)
52 #define BUFCFG_OVINEN                   BIT(12)
53 #define BUFCFG_OVINEN_EN                BIT(13)
54 #define BUFCFG_OVINEN_MASK              GENMASK(13, 12)
55 #define BUFCFG_OVOUTEN                  BIT(14)
56 #define BUFCFG_OVOUTEN_EN               BIT(15)
57 #define BUFCFG_OVOUTEN_MASK             GENMASK(15, 14)
58 #define BUFCFG_INDATAOV_VAL             BIT(16)
59 #define BUFCFG_INDATAOV_EN              BIT(17)
60 #define BUFCFG_INDATAOV_MASK            GENMASK(17, 16)
61 #define BUFCFG_OUTDATAOV_VAL            BIT(18)
62 #define BUFCFG_OUTDATAOV_EN             BIT(19)
63 #define BUFCFG_OUTDATAOV_MASK           GENMASK(19, 18)
64 #define BUFCFG_OD_EN                    BIT(21)
65
66 #define pin_to_bufno(f, p)              ((p) - (f)->pin_base)
67
68 static const struct tng_family *tng_get_family(struct tng_pinctrl *tp,
69                                                unsigned int pin)
70 {
71         const struct tng_family *family;
72         unsigned int i;
73
74         for (i = 0; i < tp->nfamilies; i++) {
75                 family = &tp->families[i];
76                 if (pin >= family->pin_base &&
77                     pin < family->pin_base + family->npins)
78                         return family;
79         }
80
81         dev_warn(tp->dev, "failed to find family for pin %u\n", pin);
82         return NULL;
83 }
84
85 static bool tng_buf_available(struct tng_pinctrl *tp, unsigned int pin)
86 {
87         const struct tng_family *family;
88
89         family = tng_get_family(tp, pin);
90         if (!family)
91                 return false;
92
93         return !family->protected;
94 }
95
96 static void __iomem *tng_get_bufcfg(struct tng_pinctrl *tp, unsigned int pin)
97 {
98         const struct tng_family *family;
99         unsigned int bufno;
100
101         family = tng_get_family(tp, pin);
102         if (!family)
103                 return NULL;
104
105         bufno = pin_to_bufno(family, pin);
106         return family->regs + BUFCFG_OFFSET + bufno * 4;
107 }
108
109 static int tng_read_bufcfg(struct tng_pinctrl *tp, unsigned int pin, u32 *value)
110 {
111         void __iomem *bufcfg;
112
113         if (!tng_buf_available(tp, pin))
114                 return -EBUSY;
115
116         bufcfg = tng_get_bufcfg(tp, pin);
117         *value = readl(bufcfg);
118
119         return 0;
120 }
121
122 static void tng_update_bufcfg(struct tng_pinctrl *tp, unsigned int pin,
123                               u32 bits, u32 mask)
124 {
125         void __iomem *bufcfg;
126         u32 value;
127
128         bufcfg = tng_get_bufcfg(tp, pin);
129
130         value = readl(bufcfg);
131         value = (value & ~mask) | (bits & mask);
132         writel(value, bufcfg);
133 }
134
135 static int tng_get_groups_count(struct pinctrl_dev *pctldev)
136 {
137         struct tng_pinctrl *tp = pinctrl_dev_get_drvdata(pctldev);
138
139         return tp->ngroups;
140 }
141
142 static const char *tng_get_group_name(struct pinctrl_dev *pctldev,
143                                       unsigned int group)
144 {
145         struct tng_pinctrl *tp = pinctrl_dev_get_drvdata(pctldev);
146
147         return tp->groups[group].grp.name;
148 }
149
150 static int tng_get_group_pins(struct pinctrl_dev *pctldev, unsigned int group,
151                               const unsigned int **pins, unsigned int *npins)
152 {
153         struct tng_pinctrl *tp = pinctrl_dev_get_drvdata(pctldev);
154
155         *pins = tp->groups[group].grp.pins;
156         *npins = tp->groups[group].grp.npins;
157         return 0;
158 }
159
160 static void tng_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
161                              unsigned int pin)
162 {
163         struct tng_pinctrl *tp = pinctrl_dev_get_drvdata(pctldev);
164         u32 value, mode;
165         int ret;
166
167         ret = tng_read_bufcfg(tp, pin, &value);
168         if (ret) {
169                 seq_puts(s, "not available");
170                 return;
171         }
172
173         mode = (value & BUFCFG_PINMODE_MASK) >> BUFCFG_PINMODE_SHIFT;
174         if (mode == BUFCFG_PINMODE_GPIO)
175                 seq_puts(s, "GPIO ");
176         else
177                 seq_printf(s, "mode %d ", mode);
178
179         seq_printf(s, "0x%08x", value);
180 }
181
182 static const struct pinctrl_ops tng_pinctrl_ops = {
183         .get_groups_count = tng_get_groups_count,
184         .get_group_name = tng_get_group_name,
185         .get_group_pins = tng_get_group_pins,
186         .pin_dbg_show = tng_pin_dbg_show,
187 };
188
189 static int tng_get_functions_count(struct pinctrl_dev *pctldev)
190 {
191         struct tng_pinctrl *tp = pinctrl_dev_get_drvdata(pctldev);
192
193         return tp->nfunctions;
194 }
195
196 static const char *tng_get_function_name(struct pinctrl_dev *pctldev,
197                                          unsigned int function)
198 {
199         struct tng_pinctrl *tp = pinctrl_dev_get_drvdata(pctldev);
200
201         return tp->functions[function].func.name;
202 }
203
204 static int tng_get_function_groups(struct pinctrl_dev *pctldev,
205                                    unsigned int function,
206                                    const char * const **groups,
207                                    unsigned int * const ngroups)
208 {
209         struct tng_pinctrl *tp = pinctrl_dev_get_drvdata(pctldev);
210
211         *groups = tp->functions[function].func.groups;
212         *ngroups = tp->functions[function].func.ngroups;
213         return 0;
214 }
215
216 static int tng_pinmux_set_mux(struct pinctrl_dev *pctldev,
217                               unsigned int function,
218                               unsigned int group)
219 {
220         struct tng_pinctrl *tp = pinctrl_dev_get_drvdata(pctldev);
221         const struct intel_pingroup *grp = &tp->groups[group];
222         u32 bits = grp->mode << BUFCFG_PINMODE_SHIFT;
223         u32 mask = BUFCFG_PINMODE_MASK;
224         unsigned int i;
225
226         /*
227          * All pins in the groups needs to be accessible and writable
228          * before we can enable the mux for this group.
229          */
230         for (i = 0; i < grp->grp.npins; i++) {
231                 if (!tng_buf_available(tp, grp->grp.pins[i]))
232                         return -EBUSY;
233         }
234
235         guard(raw_spinlock_irqsave)(&tp->lock);
236
237         /* Now enable the mux setting for each pin in the group */
238         for (i = 0; i < grp->grp.npins; i++)
239                 tng_update_bufcfg(tp, grp->grp.pins[i], bits, mask);
240
241         return 0;
242 }
243
244 static int tng_gpio_request_enable(struct pinctrl_dev *pctldev,
245                                    struct pinctrl_gpio_range *range,
246                                    unsigned int pin)
247 {
248         struct tng_pinctrl *tp = pinctrl_dev_get_drvdata(pctldev);
249         u32 bits = BUFCFG_PINMODE_GPIO << BUFCFG_PINMODE_SHIFT;
250         u32 mask = BUFCFG_PINMODE_MASK;
251
252         if (!tng_buf_available(tp, pin))
253                 return -EBUSY;
254
255         guard(raw_spinlock_irqsave)(&tp->lock);
256
257         tng_update_bufcfg(tp, pin, bits, mask);
258
259         return 0;
260 }
261
262 static const struct pinmux_ops tng_pinmux_ops = {
263         .get_functions_count = tng_get_functions_count,
264         .get_function_name = tng_get_function_name,
265         .get_function_groups = tng_get_function_groups,
266         .set_mux = tng_pinmux_set_mux,
267         .gpio_request_enable = tng_gpio_request_enable,
268 };
269
270 static int tng_config_get(struct pinctrl_dev *pctldev, unsigned int pin,
271                           unsigned long *config)
272 {
273         struct tng_pinctrl *tp = pinctrl_dev_get_drvdata(pctldev);
274         enum pin_config_param param = pinconf_to_config_param(*config);
275         u32 value, term;
276         u16 arg = 0;
277         int ret;
278
279         ret = tng_read_bufcfg(tp, pin, &value);
280         if (ret)
281                 return -ENOTSUPP;
282
283         term = (value & BUFCFG_PUPD_VAL_MASK) >> BUFCFG_PUPD_VAL_SHIFT;
284
285         switch (param) {
286         case PIN_CONFIG_BIAS_DISABLE:
287                 if (value & BUFCFG_Px_EN_MASK)
288                         return -EINVAL;
289                 break;
290
291         case PIN_CONFIG_BIAS_PULL_UP:
292                 if ((value & BUFCFG_Px_EN_MASK) != BUFCFG_PU_EN)
293                         return -EINVAL;
294
295                 switch (term) {
296                 case BUFCFG_PUPD_VAL_910:
297                         arg = 910;
298                         break;
299                 case BUFCFG_PUPD_VAL_2K:
300                         arg = 2000;
301                         break;
302                 case BUFCFG_PUPD_VAL_20K:
303                         arg = 20000;
304                         break;
305                 case BUFCFG_PUPD_VAL_50K:
306                         arg = 50000;
307                         break;
308                 }
309
310                 break;
311
312         case PIN_CONFIG_BIAS_PULL_DOWN:
313                 if ((value & BUFCFG_Px_EN_MASK) != BUFCFG_PD_EN)
314                         return -EINVAL;
315
316                 switch (term) {
317                 case BUFCFG_PUPD_VAL_910:
318                         arg = 910;
319                         break;
320                 case BUFCFG_PUPD_VAL_2K:
321                         arg = 2000;
322                         break;
323                 case BUFCFG_PUPD_VAL_20K:
324                         arg = 20000;
325                         break;
326                 case BUFCFG_PUPD_VAL_50K:
327                         arg = 50000;
328                         break;
329                 }
330
331                 break;
332
333         case PIN_CONFIG_DRIVE_PUSH_PULL:
334                 if (value & BUFCFG_OD_EN)
335                         return -EINVAL;
336                 break;
337
338         case PIN_CONFIG_DRIVE_OPEN_DRAIN:
339                 if (!(value & BUFCFG_OD_EN))
340                         return -EINVAL;
341                 break;
342
343         case PIN_CONFIG_SLEW_RATE:
344                 if (value & BUFCFG_SLEWSEL)
345                         arg = 1;
346                 break;
347
348         default:
349                 return -ENOTSUPP;
350         }
351
352         *config = pinconf_to_config_packed(param, arg);
353         return 0;
354 }
355
356 static int tng_config_set_pin(struct tng_pinctrl *tp, unsigned int pin,
357                               unsigned long config)
358 {
359         unsigned int param = pinconf_to_config_param(config);
360         unsigned int arg = pinconf_to_config_argument(config);
361         u32 mask, term, value = 0;
362
363         switch (param) {
364         case PIN_CONFIG_BIAS_DISABLE:
365                 mask = BUFCFG_Px_EN_MASK | BUFCFG_PUPD_VAL_MASK;
366                 break;
367
368         case PIN_CONFIG_BIAS_PULL_UP:
369                 switch (arg) {
370                 case 50000:
371                         term = BUFCFG_PUPD_VAL_50K;
372                         break;
373                 case 1: /* Set default strength value in case none is given */
374                 case 20000:
375                         term = BUFCFG_PUPD_VAL_20K;
376                         break;
377                 case 2000:
378                         term = BUFCFG_PUPD_VAL_2K;
379                         break;
380                 case 910:
381                         term = BUFCFG_PUPD_VAL_910;
382                         break;
383                 default:
384                         return -EINVAL;
385                 }
386
387                 mask = BUFCFG_Px_EN_MASK | BUFCFG_PUPD_VAL_MASK;
388                 value = BUFCFG_PU_EN | (term << BUFCFG_PUPD_VAL_SHIFT);
389                 break;
390
391         case PIN_CONFIG_BIAS_PULL_DOWN:
392                 switch (arg) {
393                 case 50000:
394                         term = BUFCFG_PUPD_VAL_50K;
395                         break;
396                 case 1: /* Set default strength value in case none is given */
397                 case 20000:
398                         term = BUFCFG_PUPD_VAL_20K;
399                         break;
400                 case 2000:
401                         term = BUFCFG_PUPD_VAL_2K;
402                         break;
403                 case 910:
404                         term = BUFCFG_PUPD_VAL_910;
405                         break;
406                 default:
407                         return -EINVAL;
408                 }
409
410                 mask = BUFCFG_Px_EN_MASK | BUFCFG_PUPD_VAL_MASK;
411                 value = BUFCFG_PD_EN | (term << BUFCFG_PUPD_VAL_SHIFT);
412                 break;
413
414         case PIN_CONFIG_DRIVE_PUSH_PULL:
415                 mask = BUFCFG_OD_EN;
416                 break;
417
418         case PIN_CONFIG_DRIVE_OPEN_DRAIN:
419                 mask = BUFCFG_OD_EN;
420                 value = BUFCFG_OD_EN;
421                 break;
422
423         case PIN_CONFIG_SLEW_RATE:
424                 mask = BUFCFG_SLEWSEL;
425                 if (arg)
426                         value = BUFCFG_SLEWSEL;
427                 break;
428
429         default:
430                 return -EINVAL;
431         }
432
433         guard(raw_spinlock_irqsave)(&tp->lock);
434
435         tng_update_bufcfg(tp, pin, value, mask);
436
437         return 0;
438 }
439
440 static int tng_config_set(struct pinctrl_dev *pctldev, unsigned int pin,
441                           unsigned long *configs, unsigned int nconfigs)
442 {
443         struct tng_pinctrl *tp = pinctrl_dev_get_drvdata(pctldev);
444         unsigned int i;
445         int ret;
446
447         if (!tng_buf_available(tp, pin))
448                 return -ENOTSUPP;
449
450         for (i = 0; i < nconfigs; i++) {
451                 switch (pinconf_to_config_param(configs[i])) {
452                 case PIN_CONFIG_BIAS_DISABLE:
453                 case PIN_CONFIG_BIAS_PULL_UP:
454                 case PIN_CONFIG_BIAS_PULL_DOWN:
455                 case PIN_CONFIG_DRIVE_PUSH_PULL:
456                 case PIN_CONFIG_DRIVE_OPEN_DRAIN:
457                 case PIN_CONFIG_SLEW_RATE:
458                         ret = tng_config_set_pin(tp, pin, configs[i]);
459                         if (ret)
460                                 return ret;
461                         break;
462
463                 default:
464                         return -ENOTSUPP;
465                 }
466         }
467
468         return 0;
469 }
470
471 static int tng_config_group_get(struct pinctrl_dev *pctldev,
472                                 unsigned int group, unsigned long *config)
473 {
474         const unsigned int *pins;
475         unsigned int npins;
476         int ret;
477
478         ret = tng_get_group_pins(pctldev, group, &pins, &npins);
479         if (ret)
480                 return ret;
481
482         return tng_config_get(pctldev, pins[0], config);
483 }
484
485 static int tng_config_group_set(struct pinctrl_dev *pctldev,
486                                 unsigned int group, unsigned long *configs,
487                                 unsigned int num_configs)
488 {
489         const unsigned int *pins;
490         unsigned int npins;
491         int i, ret;
492
493         ret = tng_get_group_pins(pctldev, group, &pins, &npins);
494         if (ret)
495                 return ret;
496
497         for (i = 0; i < npins; i++) {
498                 ret = tng_config_set(pctldev, pins[i], configs, num_configs);
499                 if (ret)
500                         return ret;
501         }
502
503         return 0;
504 }
505
506 static const struct pinconf_ops tng_pinconf_ops = {
507         .is_generic = true,
508         .pin_config_get = tng_config_get,
509         .pin_config_set = tng_config_set,
510         .pin_config_group_get = tng_config_group_get,
511         .pin_config_group_set = tng_config_group_set,
512 };
513
514 static const struct pinctrl_desc tng_pinctrl_desc = {
515         .pctlops = &tng_pinctrl_ops,
516         .pmxops = &tng_pinmux_ops,
517         .confops = &tng_pinconf_ops,
518         .owner = THIS_MODULE,
519 };
520
521 static int tng_pinctrl_probe(struct platform_device *pdev,
522                              const struct tng_pinctrl *data)
523 {
524         struct device *dev = &pdev->dev;
525         struct tng_family *families;
526         struct tng_pinctrl *tp;
527         size_t families_len;
528         void __iomem *regs;
529         unsigned int i;
530
531         tp = devm_kmemdup(dev, data, sizeof(*data), GFP_KERNEL);
532         if (!tp)
533                 return -ENOMEM;
534
535         tp->dev = dev;
536         raw_spin_lock_init(&tp->lock);
537
538         regs = devm_platform_ioremap_resource(pdev, 0);
539         if (IS_ERR(regs))
540                 return PTR_ERR(regs);
541
542         /*
543          * Make a copy of the families which we can use to hold pointers
544          * to the registers.
545          */
546         families_len = size_mul(sizeof(*families), tp->nfamilies);
547         families = devm_kmemdup(dev, tp->families, families_len, GFP_KERNEL);
548         if (!families)
549                 return -ENOMEM;
550
551         /* Splice memory resource by chunk per family */
552         for (i = 0; i < tp->nfamilies; i++) {
553                 struct tng_family *family = &families[i];
554
555                 family->regs = regs + family->barno * TNG_FAMILY_LEN;
556         }
557
558         tp->families = families;
559         tp->pctldesc = tng_pinctrl_desc;
560         tp->pctldesc.name = dev_name(dev);
561         tp->pctldesc.pins = tp->pins;
562         tp->pctldesc.npins = tp->npins;
563
564         tp->pctldev = devm_pinctrl_register(dev, &tp->pctldesc, tp);
565         if (IS_ERR(tp->pctldev))
566                 return dev_err_probe(dev, PTR_ERR(tp->pctldev),
567                                      "failed to register pinctrl driver\n");
568
569         return 0;
570 }
571
572 int devm_tng_pinctrl_probe(struct platform_device *pdev)
573 {
574         const struct tng_pinctrl *data;
575
576         data = device_get_match_data(&pdev->dev);
577         if (!data)
578                 return -ENODATA;
579
580         return tng_pinctrl_probe(pdev, data);
581 }
582 EXPORT_SYMBOL_NS_GPL(devm_tng_pinctrl_probe, PINCTRL_TANGIER);
583
584 MODULE_AUTHOR("Andy Shevchenko <andriy.shevchenko@linux.intel.com>");
585 MODULE_AUTHOR("Raag Jadav <raag.jadav@intel.com>");
586 MODULE_DESCRIPTION("Intel Tangier pinctrl driver");
587 MODULE_LICENSE("GPL");