Merge tag 'dm-pull-6feb20' of https://gitlab.denx.de/u-boot/custodians/u-boot-dm
[oweals/u-boot.git] / drivers / pinctrl / uniphier / pinctrl-uniphier-core.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2015-2016 Socionext Inc.
4  *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
5  */
6
7 #include <common.h>
8 #include <dm.h>
9 #include <dm/device_compat.h>
10 #include <linux/io.h>
11 #include <linux/err.h>
12 #include <linux/kernel.h>
13 #include <linux/sizes.h>
14 #include <dm/pinctrl.h>
15
16 #include "pinctrl-uniphier.h"
17
18 #define UNIPHIER_PINCTRL_PINMUX_BASE    0x1000
19 #define UNIPHIER_PINCTRL_LOAD_PINMUX    0x1700
20 #define UNIPHIER_PINCTRL_DRVCTRL_BASE   0x1800
21 #define UNIPHIER_PINCTRL_DRV2CTRL_BASE  0x1900
22 #define UNIPHIER_PINCTRL_DRV3CTRL_BASE  0x1980
23 #define UNIPHIER_PINCTRL_PUPDCTRL_BASE  0x1a00
24 #define UNIPHIER_PINCTRL_IECTRL         0x1d00
25
26 static const char *uniphier_pinctrl_dummy_name = "_dummy";
27
28 static int uniphier_pinctrl_get_pins_count(struct udevice *dev)
29 {
30         struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
31         const struct uniphier_pinctrl_pin *pins = priv->socdata->pins;
32         int pins_count = priv->socdata->pins_count;
33
34         /*
35          * We do not list all pins in the pin table to save memory footprint.
36          * Report the max pin number + 1 to fake the framework.
37          */
38         return pins[pins_count - 1].number + 1;
39 }
40
41 static const char *uniphier_pinctrl_get_pin_name(struct udevice *dev,
42                                                  unsigned int selector)
43 {
44         struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
45         const struct uniphier_pinctrl_pin *pins = priv->socdata->pins;
46         int pins_count = priv->socdata->pins_count;
47         int i;
48
49         for (i = 0; i < pins_count; i++)
50                 if (pins[i].number == selector)
51                         return pins[i].name;
52
53         return uniphier_pinctrl_dummy_name;
54 }
55
56 static int uniphier_pinctrl_get_groups_count(struct udevice *dev)
57 {
58         struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
59
60         return priv->socdata->groups_count;
61 }
62
63 static const char *uniphier_pinctrl_get_group_name(struct udevice *dev,
64                                                    unsigned selector)
65 {
66         struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
67
68         if (!priv->socdata->groups[selector].name)
69                 return uniphier_pinctrl_dummy_name;
70
71         return priv->socdata->groups[selector].name;
72 }
73
74 static int uniphier_pinmux_get_functions_count(struct udevice *dev)
75 {
76         struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
77
78         return priv->socdata->functions_count;
79 }
80
81 static const char *uniphier_pinmux_get_function_name(struct udevice *dev,
82                                                      unsigned selector)
83 {
84         struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
85
86         if (!priv->socdata->functions[selector])
87                 return uniphier_pinctrl_dummy_name;
88
89         return priv->socdata->functions[selector];
90 }
91
92 static int uniphier_pinconf_input_enable_perpin(struct udevice *dev,
93                                                 unsigned int pin, int enable)
94 {
95         struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
96         unsigned reg;
97         u32 mask, tmp;
98
99         reg = UNIPHIER_PINCTRL_IECTRL + pin / 32 * 4;
100         mask = BIT(pin % 32);
101
102         tmp = readl(priv->base + reg);
103         if (enable)
104                 tmp |= mask;
105         else
106                 tmp &= ~mask;
107         writel(tmp, priv->base + reg);
108
109         return 0;
110 }
111
112 static int uniphier_pinconf_input_enable_legacy(struct udevice *dev,
113                                                 unsigned int pin, int enable)
114 {
115         struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
116
117         /*
118          * Multiple pins share one input enable, per-pin disabling is
119          * impossible.
120          */
121         if (!enable)
122                 return -EINVAL;
123
124         /* Set all bits instead of having a bunch of pin data */
125         writel(U32_MAX, priv->base + UNIPHIER_PINCTRL_IECTRL);
126
127         return 0;
128 }
129
130 static int uniphier_pinconf_input_enable(struct udevice *dev,
131                                          unsigned int pin, int enable)
132 {
133         struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
134
135         if (priv->socdata->caps & UNIPHIER_PINCTRL_CAPS_PERPIN_IECTRL)
136                 return uniphier_pinconf_input_enable_perpin(dev, pin, enable);
137         else
138                 return uniphier_pinconf_input_enable_legacy(dev, pin, enable);
139 }
140
141 #if CONFIG_IS_ENABLED(PINCONF)
142
143 static const struct pinconf_param uniphier_pinconf_params[] = {
144         { "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 },
145         { "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 },
146         { "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 },
147         { "bias-pull-pin-default", PIN_CONFIG_BIAS_PULL_PIN_DEFAULT, 1 },
148         { "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 0 },
149         { "input-enable", PIN_CONFIG_INPUT_ENABLE, 1 },
150         { "input-disable", PIN_CONFIG_INPUT_ENABLE, 0 },
151 };
152
153 static const struct uniphier_pinctrl_pin *
154 uniphier_pinctrl_pin_get(struct uniphier_pinctrl_priv *priv, unsigned int pin)
155 {
156         const struct uniphier_pinctrl_pin *pins = priv->socdata->pins;
157         int pins_count = priv->socdata->pins_count;
158         int i;
159
160         for (i = 0; i < pins_count; i++)
161                 if (pins[i].number == pin)
162                         return &pins[i];
163
164         return NULL;
165 }
166
167 static int uniphier_pinconf_bias_set(struct udevice *dev, unsigned int pin,
168                                      unsigned int param, unsigned int arg)
169 {
170         struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
171         unsigned int enable = 1;
172         unsigned int reg;
173         u32 mask, tmp;
174
175         if (!(priv->socdata->caps & UNIPHIER_PINCTRL_CAPS_PUPD_SIMPLE))
176                 return -ENOTSUPP;
177
178         switch (param) {
179         case PIN_CONFIG_BIAS_DISABLE:
180                 enable = 0;
181                 break;
182         case PIN_CONFIG_BIAS_PULL_UP:
183         case PIN_CONFIG_BIAS_PULL_DOWN:
184                 if (arg == 0)   /* total bias is not supported */
185                         return -EINVAL;
186                 break;
187         case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
188                 if (arg == 0)   /* configuration ignored */
189                         return 0;
190         default:
191                 BUG();
192         }
193
194         reg = UNIPHIER_PINCTRL_PUPDCTRL_BASE + pin / 32 * 4;
195         mask = BIT(pin % 32);
196
197         tmp = readl(priv->base + reg);
198         if (enable)
199                 tmp |= mask;
200         else
201                 tmp &= ~mask;
202         writel(tmp, priv->base + reg);
203
204         return 0;
205 }
206
207 static const unsigned int uniphier_pinconf_drv_strengths_1bit[] = {
208         4, 8,
209 };
210
211 static const unsigned int uniphier_pinconf_drv_strengths_2bit[] = {
212         8, 12, 16, 20,
213 };
214
215 static const unsigned int uniphier_pinconf_drv_strengths_3bit[] = {
216         4, 5, 7, 9, 11, 12, 14, 16,
217 };
218
219 static int uniphier_pinconf_drive_set(struct udevice *dev, unsigned int pin,
220                                       unsigned int strength)
221 {
222         struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
223         const struct uniphier_pinctrl_pin *desc;
224         const unsigned int *strengths;
225         unsigned int base, stride, width, drvctrl, reg, shift;
226         u32 val, mask, tmp;
227
228         desc = uniphier_pinctrl_pin_get(priv, pin);
229         if (WARN_ON(!desc))
230                 return -EINVAL;
231
232         switch (uniphier_pin_get_drv_type(desc->data)) {
233         case UNIPHIER_PIN_DRV_1BIT:
234                 strengths = uniphier_pinconf_drv_strengths_1bit;
235                 base = UNIPHIER_PINCTRL_DRVCTRL_BASE;
236                 stride = 1;
237                 width = 1;
238                 break;
239         case UNIPHIER_PIN_DRV_2BIT:
240                 strengths = uniphier_pinconf_drv_strengths_2bit;
241                 base = UNIPHIER_PINCTRL_DRV2CTRL_BASE;
242                 stride = 2;
243                 width = 2;
244                 break;
245         case UNIPHIER_PIN_DRV_3BIT:
246                 strengths = uniphier_pinconf_drv_strengths_3bit;
247                 base = UNIPHIER_PINCTRL_DRV3CTRL_BASE;
248                 stride = 4;
249                 width = 3;
250                 break;
251         default:
252                 /* drive strength control is not supported for this pin */
253                 return -EINVAL;
254         }
255
256         drvctrl = uniphier_pin_get_drvctrl(desc->data);
257         drvctrl *= stride;
258
259         reg = base + drvctrl / 32 * 4;
260         shift = drvctrl % 32;
261         mask = (1U << width) - 1;
262
263         for (val = 0; val <= mask; val++) {
264                 if (strengths[val] > strength)
265                         break;
266         }
267
268         if (val == 0) {
269                 dev_err(dev, "unsupported drive strength %u mA for pin %s\n",
270                         strength, desc->name);
271                 return -EINVAL;
272         }
273
274         if (!mask)
275                 return 0;
276
277         val--;
278
279         tmp = readl(priv->base + reg);
280         tmp &= ~(mask << shift);
281         tmp |= (mask & val) << shift;
282         writel(tmp, priv->base + reg);
283
284         return 0;
285 }
286
287 static int uniphier_pinconf_set(struct udevice *dev, unsigned int pin,
288                                 unsigned int param, unsigned int arg)
289 {
290         int ret;
291
292         switch (param) {
293         case PIN_CONFIG_BIAS_DISABLE:
294         case PIN_CONFIG_BIAS_PULL_UP:
295         case PIN_CONFIG_BIAS_PULL_DOWN:
296         case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
297                 ret = uniphier_pinconf_bias_set(dev, pin, param, arg);
298                 break;
299         case PIN_CONFIG_DRIVE_STRENGTH:
300                 ret = uniphier_pinconf_drive_set(dev, pin, arg);
301                 break;
302         case PIN_CONFIG_INPUT_ENABLE:
303                 ret = uniphier_pinconf_input_enable(dev, pin, arg);
304                 break;
305         default:
306                 dev_err(dev, "unsupported configuration parameter %u\n", param);
307                 return -EINVAL;
308         }
309
310         return ret;
311 }
312
313 static int uniphier_pinconf_group_set(struct udevice *dev,
314                                       unsigned int group_selector,
315                                       unsigned int param, unsigned int arg)
316 {
317         struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
318         const struct uniphier_pinctrl_group *grp =
319                                         &priv->socdata->groups[group_selector];
320         int i, ret;
321
322         for (i = 0; i < grp->num_pins; i++) {
323                 ret = uniphier_pinconf_set(dev, grp->pins[i], param, arg);
324                 if (ret)
325                         return ret;
326         }
327
328         return 0;
329 }
330
331 #endif /* CONFIG_IS_ENABLED(PINCONF) */
332
333 static void uniphier_pinmux_set_one(struct udevice *dev, unsigned pin,
334                                     int muxval)
335 {
336         struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
337         unsigned reg, reg_end, shift, mask;
338         unsigned mux_bits = 8;
339         unsigned reg_stride = 4;
340         bool load_pinctrl = false;
341         u32 tmp;
342
343         /* some pins need input-enabling */
344         uniphier_pinconf_input_enable(dev, pin, 1);
345
346         if (muxval < 0)
347                 return;         /* dedicated pin; nothing to do for pin-mux */
348
349         if (priv->socdata->caps & UNIPHIER_PINCTRL_CAPS_MUX_4BIT)
350                 mux_bits = 4;
351
352         if (priv->socdata->caps & UNIPHIER_PINCTRL_CAPS_DBGMUX_SEPARATE) {
353                 /*
354                  *  Mode       offset        bit
355                  *  Normal     4 * n     shift+3:shift
356                  *  Debug      4 * n     shift+7:shift+4
357                  */
358                 mux_bits /= 2;
359                 reg_stride = 8;
360                 load_pinctrl = true;
361         }
362
363         reg = UNIPHIER_PINCTRL_PINMUX_BASE + pin * mux_bits / 32 * reg_stride;
364         reg_end = reg + reg_stride;
365         shift = pin * mux_bits % 32;
366         mask = (1U << mux_bits) - 1;
367
368         /*
369          * If reg_stride is greater than 4, the MSB of each pinsel shall be
370          * stored in the offset+4.
371          */
372         for (; reg < reg_end; reg += 4) {
373                 tmp = readl(priv->base + reg);
374                 tmp &= ~(mask << shift);
375                 tmp |= (mask & muxval) << shift;
376                 writel(tmp, priv->base + reg);
377
378                 muxval >>= mux_bits;
379         }
380
381         if (load_pinctrl)
382                 writel(1, priv->base + UNIPHIER_PINCTRL_LOAD_PINMUX);
383 }
384
385 static int uniphier_pinmux_group_set(struct udevice *dev,
386                                      unsigned group_selector,
387                                      unsigned func_selector)
388 {
389         struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
390         const struct uniphier_pinctrl_group *grp =
391                                         &priv->socdata->groups[group_selector];
392         int i;
393
394         for (i = 0; i < grp->num_pins; i++)
395                 uniphier_pinmux_set_one(dev, grp->pins[i], grp->muxvals[i]);
396
397         return 0;
398 }
399
400 const struct pinctrl_ops uniphier_pinctrl_ops = {
401         .get_pins_count = uniphier_pinctrl_get_pins_count,
402         .get_pin_name = uniphier_pinctrl_get_pin_name,
403         .get_groups_count = uniphier_pinctrl_get_groups_count,
404         .get_group_name = uniphier_pinctrl_get_group_name,
405         .get_functions_count = uniphier_pinmux_get_functions_count,
406         .get_function_name = uniphier_pinmux_get_function_name,
407         .pinmux_group_set = uniphier_pinmux_group_set,
408 #if CONFIG_IS_ENABLED(PINCONF)
409         .pinconf_num_params = ARRAY_SIZE(uniphier_pinconf_params),
410         .pinconf_params = uniphier_pinconf_params,
411         .pinconf_set = uniphier_pinconf_set,
412         .pinconf_group_set = uniphier_pinconf_group_set,
413 #endif
414         .set_state = pinctrl_generic_set_state,
415 };
416
417 int uniphier_pinctrl_probe(struct udevice *dev,
418                            struct uniphier_pinctrl_socdata *socdata)
419 {
420         struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
421         fdt_addr_t addr;
422
423         addr = devfdt_get_addr(dev->parent);
424         if (addr == FDT_ADDR_T_NONE)
425                 return -EINVAL;
426
427         priv->base = devm_ioremap(dev, addr, SZ_4K);
428         if (!priv->base)
429                 return -ENOMEM;
430
431         priv->socdata = socdata;
432
433         return 0;
434 }