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