efi_loader: correctly render MAC address device path nodes
[oweals/u-boot.git] / drivers / pinctrl / meson / pinctrl-meson.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2016 - Beniamino Galvani <b.galvani@gmail.com>
4  */
5
6 #include <common.h>
7 #include <dm.h>
8 #include <dm/device-internal.h>
9 #include <dm/lists.h>
10 #include <dm/pinctrl.h>
11 #include <fdt_support.h>
12 #include <linux/err.h>
13 #include <linux/io.h>
14 #include <linux/sizes.h>
15 #include <asm/gpio.h>
16
17 #include "pinctrl-meson.h"
18
19 DECLARE_GLOBAL_DATA_PTR;
20
21 static const char *meson_pinctrl_dummy_name = "_dummy";
22
23 static char pin_name[PINNAME_SIZE];
24
25 int meson_pinctrl_get_groups_count(struct udevice *dev)
26 {
27         struct meson_pinctrl *priv = dev_get_priv(dev);
28
29         return priv->data->num_groups;
30 }
31
32 const char *meson_pinctrl_get_group_name(struct udevice *dev,
33                                          unsigned int selector)
34 {
35         struct meson_pinctrl *priv = dev_get_priv(dev);
36
37         if (!priv->data->groups[selector].name)
38                 return meson_pinctrl_dummy_name;
39
40         return priv->data->groups[selector].name;
41 }
42
43 int meson_pinctrl_get_pins_count(struct udevice *dev)
44 {
45         struct meson_pinctrl *priv = dev_get_priv(dev);
46
47         return priv->data->num_pins;
48 }
49
50 const char *meson_pinctrl_get_pin_name(struct udevice *dev,
51                                        unsigned int selector)
52 {
53         struct meson_pinctrl *priv = dev_get_priv(dev);
54
55         if (selector > priv->data->num_pins ||
56             selector > priv->data->funcs[0].num_groups)
57                 snprintf(pin_name, PINNAME_SIZE, "Error");
58         else
59                 snprintf(pin_name, PINNAME_SIZE, "%s",
60                          priv->data->funcs[0].groups[selector]);
61
62         return pin_name;
63 }
64
65 int meson_pinmux_get_functions_count(struct udevice *dev)
66 {
67         struct meson_pinctrl *priv = dev_get_priv(dev);
68
69         return priv->data->num_funcs;
70 }
71
72 const char *meson_pinmux_get_function_name(struct udevice *dev,
73                                            unsigned int selector)
74 {
75         struct meson_pinctrl *priv = dev_get_priv(dev);
76
77         return priv->data->funcs[selector].name;
78 }
79
80 static int meson_gpio_calc_reg_and_bit(struct udevice *dev, unsigned int offset,
81                                        enum meson_reg_type reg_type,
82                                        unsigned int *reg, unsigned int *bit)
83 {
84         struct meson_pinctrl *priv = dev_get_priv(dev);
85         struct meson_bank *bank = NULL;
86         struct meson_reg_desc *desc;
87         unsigned int pin;
88         int i;
89
90         pin = priv->data->pin_base + offset;
91
92         for (i = 0; i < priv->data->num_banks; i++) {
93                 if (pin >= priv->data->banks[i].first &&
94                     pin <= priv->data->banks[i].last) {
95                         bank = &priv->data->banks[i];
96                         break;
97                 }
98         }
99
100         if (!bank)
101                 return -EINVAL;
102
103         desc = &bank->regs[reg_type];
104         *reg = desc->reg * 4;
105         *bit = desc->bit + pin - bank->first;
106
107         return 0;
108 }
109
110 int meson_gpio_get(struct udevice *dev, unsigned int offset)
111 {
112         struct meson_pinctrl *priv = dev_get_priv(dev->parent);
113         unsigned int reg, bit;
114         int ret;
115
116         ret = meson_gpio_calc_reg_and_bit(dev->parent, offset, REG_IN, &reg,
117                                           &bit);
118         if (ret)
119                 return ret;
120
121         return !!(readl(priv->reg_gpio + reg) & BIT(bit));
122 }
123
124 int meson_gpio_set(struct udevice *dev, unsigned int offset, int value)
125 {
126         struct meson_pinctrl *priv = dev_get_priv(dev->parent);
127         unsigned int reg, bit;
128         int ret;
129
130         ret = meson_gpio_calc_reg_and_bit(dev->parent, offset, REG_OUT, &reg,
131                                           &bit);
132         if (ret)
133                 return ret;
134
135         clrsetbits_le32(priv->reg_gpio + reg, BIT(bit), value ? BIT(bit) : 0);
136
137         return 0;
138 }
139
140 int meson_gpio_get_direction(struct udevice *dev, unsigned int offset)
141 {
142         struct meson_pinctrl *priv = dev_get_priv(dev->parent);
143         unsigned int reg, bit, val;
144         int ret;
145
146         ret = meson_gpio_calc_reg_and_bit(dev->parent, offset, REG_DIR, &reg,
147                                           &bit);
148         if (ret)
149                 return ret;
150
151         val = readl(priv->reg_gpio + reg);
152
153         return (val & BIT(bit)) ? GPIOF_INPUT : GPIOF_OUTPUT;
154 }
155
156 int meson_gpio_direction_input(struct udevice *dev, unsigned int offset)
157 {
158         struct meson_pinctrl *priv = dev_get_priv(dev->parent);
159         unsigned int reg, bit;
160         int ret;
161
162         ret = meson_gpio_calc_reg_and_bit(dev->parent, offset, REG_DIR, &reg,
163                                           &bit);
164         if (ret)
165                 return ret;
166
167         setbits_le32(priv->reg_gpio + reg, BIT(bit));
168
169         return 0;
170 }
171
172 int meson_gpio_direction_output(struct udevice *dev,
173                                 unsigned int offset, int value)
174 {
175         struct meson_pinctrl *priv = dev_get_priv(dev->parent);
176         unsigned int reg, bit;
177         int ret;
178
179         ret = meson_gpio_calc_reg_and_bit(dev->parent, offset, REG_DIR, &reg,
180                                           &bit);
181         if (ret)
182                 return ret;
183
184         clrbits_le32(priv->reg_gpio + reg, BIT(bit));
185
186         ret = meson_gpio_calc_reg_and_bit(dev->parent, offset, REG_OUT, &reg,
187                                           &bit);
188         if (ret)
189                 return ret;
190
191         clrsetbits_le32(priv->reg_gpio + reg, BIT(bit), value ? BIT(bit) : 0);
192
193         return 0;
194 }
195
196 static int meson_pinconf_bias_set(struct udevice *dev, unsigned int pin,
197                                   unsigned int param)
198 {
199         struct meson_pinctrl *priv = dev_get_priv(dev);
200         unsigned int offset = pin - priv->data->pin_base;
201         unsigned int reg, bit;
202         int ret;
203
204         ret = meson_gpio_calc_reg_and_bit(dev, offset, REG_PULLEN, &reg, &bit);
205         if (ret)
206                 return ret;
207
208         if (param == PIN_CONFIG_BIAS_DISABLE) {
209                 clrsetbits_le32(priv->reg_pullen + reg, BIT(bit), 0);
210                 return 0;
211         }
212
213         /* othewise, enable the bias and select level */
214         clrsetbits_le32(priv->reg_pullen + reg, BIT(bit), 1);
215         ret = meson_gpio_calc_reg_and_bit(dev, offset, REG_PULL, &reg, &bit);
216         if (ret)
217                 return ret;
218
219         clrsetbits_le32(priv->reg_pull + reg, BIT(bit),
220                         param == PIN_CONFIG_BIAS_PULL_UP);
221
222         return 0;
223 }
224
225 static int meson_pinconf_drive_strength_set(struct udevice *dev,
226                                             unsigned int pin,
227                                             unsigned int drive_strength_ua)
228 {
229         struct meson_pinctrl *priv = dev_get_priv(dev);
230         unsigned int offset = pin - priv->data->pin_base;
231         unsigned int reg, bit;
232         unsigned int ds_val;
233         int ret;
234
235         if (!priv->reg_ds) {
236                 dev_err(dev, "drive-strength-microamp not supported\n");
237                 return -ENOTSUPP;
238         }
239
240         ret = meson_gpio_calc_reg_and_bit(dev, offset, REG_DS, &reg, &bit);
241         if (ret)
242                 return ret;
243
244         bit = bit << 1;
245
246         if (drive_strength_ua <= 500) {
247                 ds_val = MESON_PINCONF_DRV_500UA;
248         } else if (drive_strength_ua <= 2500) {
249                 ds_val = MESON_PINCONF_DRV_2500UA;
250         } else if (drive_strength_ua <= 3000) {
251                 ds_val = MESON_PINCONF_DRV_3000UA;
252         } else if (drive_strength_ua <= 4000) {
253                 ds_val = MESON_PINCONF_DRV_4000UA;
254         } else {
255                 dev_warn(dev,
256                          "pin %u: invalid drive-strength-microamp : %d , default to 4mA\n",
257                          pin, drive_strength_ua);
258                 ds_val = MESON_PINCONF_DRV_4000UA;
259         }
260
261         clrsetbits_le32(priv->reg_ds + reg, 0x3 << bit, ds_val << bit);
262
263         return 0;
264 }
265
266 int meson_pinconf_set(struct udevice *dev, unsigned int pin,
267                       unsigned int param, unsigned int arg)
268 {
269         int ret;
270
271         switch (param) {
272         case PIN_CONFIG_BIAS_DISABLE:
273         case PIN_CONFIG_BIAS_PULL_UP:
274         case PIN_CONFIG_BIAS_PULL_DOWN:
275                 ret = meson_pinconf_bias_set(dev, pin, param);
276                 break;
277         case PIN_CONFIG_DRIVE_STRENGTH_UA:
278                 ret = meson_pinconf_drive_strength_set(dev, pin, arg);
279                 break;
280         default:
281                 dev_err(dev, "unsupported configuration parameter %u\n", param);
282                 return -EINVAL;
283         }
284
285         return ret;
286 }
287
288 int meson_pinconf_group_set(struct udevice *dev,
289                             unsigned int group_selector,
290                             unsigned int param, unsigned int arg)
291 {
292         struct meson_pinctrl *priv = dev_get_priv(dev);
293         struct meson_pmx_group *grp = &priv->data->groups[group_selector];
294         int i, ret;
295
296         for (i = 0; i < grp->num_pins; i++) {
297                 ret = meson_pinconf_set(dev, grp->pins[i], param, arg);
298                 if (ret)
299                         return ret;
300         }
301
302         return 0;
303 }
304
305 int meson_gpio_probe(struct udevice *dev)
306 {
307         struct meson_pinctrl *priv = dev_get_priv(dev->parent);
308         struct gpio_dev_priv *uc_priv;
309
310         uc_priv = dev_get_uclass_priv(dev);
311         uc_priv->bank_name = priv->data->name;
312         uc_priv->gpio_count = priv->data->num_pins;
313
314         return 0;
315 }
316
317 static fdt_addr_t parse_address(int offset, const char *name, int na, int ns)
318 {
319         int index, len = 0;
320         const fdt32_t *reg;
321
322         index = fdt_stringlist_search(gd->fdt_blob, offset, "reg-names", name);
323         if (index < 0)
324                 return FDT_ADDR_T_NONE;
325
326         reg = fdt_getprop(gd->fdt_blob, offset, "reg", &len);
327         if (!reg || (len <= (index * sizeof(fdt32_t) * (na + ns))))
328                 return FDT_ADDR_T_NONE;
329
330         reg += index * (na + ns);
331
332         return fdt_translate_address((void *)gd->fdt_blob, offset, reg);
333 }
334
335 int meson_pinctrl_probe(struct udevice *dev)
336 {
337         struct meson_pinctrl *priv = dev_get_priv(dev);
338         struct uclass_driver *drv;
339         struct udevice *gpio_dev;
340         fdt_addr_t addr;
341         int node, gpio = -1, len;
342         int na, ns;
343         char *name;
344
345         na = fdt_address_cells(gd->fdt_blob, dev_of_offset(dev->parent));
346         if (na < 1) {
347                 debug("bad #address-cells\n");
348                 return -EINVAL;
349         }
350
351         ns = fdt_size_cells(gd->fdt_blob, dev_of_offset(dev->parent));
352         if (ns < 1) {
353                 debug("bad #size-cells\n");
354                 return -EINVAL;
355         }
356
357         fdt_for_each_subnode(node, gd->fdt_blob, dev_of_offset(dev)) {
358                 if (fdt_getprop(gd->fdt_blob, node, "gpio-controller", &len)) {
359                         gpio = node;
360                         break;
361                 }
362         }
363
364         if (!gpio) {
365                 debug("gpio node not found\n");
366                 return -EINVAL;
367         }
368
369         addr = parse_address(gpio, "mux", na, ns);
370         if (addr == FDT_ADDR_T_NONE) {
371                 debug("mux address not found\n");
372                 return -EINVAL;
373         }
374         priv->reg_mux = (void __iomem *)addr;
375
376         addr = parse_address(gpio, "gpio", na, ns);
377         if (addr == FDT_ADDR_T_NONE) {
378                 debug("gpio address not found\n");
379                 return -EINVAL;
380         }
381         priv->reg_gpio = (void __iomem *)addr;
382
383         addr = parse_address(gpio, "pull", na, ns);
384         /* Use gpio region if pull one is not present */
385         if (addr == FDT_ADDR_T_NONE)
386                 priv->reg_pull = priv->reg_gpio;
387         else
388                 priv->reg_pull = (void __iomem *)addr;
389
390         addr = parse_address(gpio, "pull-enable", na, ns);
391         /* Use pull region if pull-enable one is not present */
392         if (addr == FDT_ADDR_T_NONE)
393                 priv->reg_pullen = priv->reg_pull;
394         else
395                 priv->reg_pullen = (void __iomem *)addr;
396
397         addr = parse_address(gpio, "ds", na, ns);
398         /* Drive strength region is optional */
399         if (addr == FDT_ADDR_T_NONE)
400                 priv->reg_ds = NULL;
401         else
402                 priv->reg_ds = (void __iomem *)addr;
403
404         priv->data = (struct meson_pinctrl_data *)dev_get_driver_data(dev);
405
406         /* Lookup GPIO driver */
407         drv = lists_uclass_lookup(UCLASS_GPIO);
408         if (!drv) {
409                 puts("Cannot find GPIO driver\n");
410                 return -ENOENT;
411         }
412
413         name = calloc(1, 32);
414         sprintf(name, "meson-gpio");
415
416         /* Create child device UCLASS_GPIO and bind it */
417         device_bind(dev, priv->data->gpio_driver, name, NULL, gpio, &gpio_dev);
418         dev_set_of_offset(gpio_dev, gpio);
419
420         return 0;
421 }