]> git.ipfire.org Git - people/ms/u-boot.git/blame - drivers/pinctrl/mvebu/pinctrl-armada-37xx.c
pinctrl: armada-37xx: Add pin controller support for Armada 37xx
[people/ms/u-boot.git] / drivers / pinctrl / mvebu / pinctrl-armada-37xx.c
CommitLineData
08718066
GC
1/*
2 * U-Boot Marvell 37xx SoC pinctrl driver
3 *
4 * Copyright (C) 2017 Stefan Roese <sr@denx.de>
5 *
6 * This driver is based on the Linux driver version, which is:
7 * Copyright (C) 2017 Marvell
8 * Gregory CLEMENT <gregory.clement@free-electrons.com>
9 *
10 * Additionally parts are derived from the Meson U-Boot pinctrl driver,
11 * which is:
12 * (C) Copyright 2016 - Beniamino Galvani <b.galvani@gmail.com>
13 * Based on code from Linux kernel:
14 * Copyright (C) 2016 Endless Mobile, Inc.
15 *
16 * SPDX-License-Identifier: GPL-2.0+
17 * https://spdx.org/licenses
18 */
19
20#include <common.h>
21#include <config.h>
22#include <dm.h>
23#include <dm/pinctrl.h>
24#include <dm/root.h>
25#include <errno.h>
26#include <fdtdec.h>
27#include <regmap.h>
28#include <asm/system.h>
29#include <asm/io.h>
30
31DECLARE_GLOBAL_DATA_PTR;
32
33#define OUTPUT_EN 0x0
34#define OUTPUT_CTL 0x20
35#define SELECTION 0x30
36
37#define IRQ_EN 0x0
38#define IRQ_POL 0x08
39#define IRQ_STATUS 0x10
40#define IRQ_WKUP 0x18
41
42#define NB_FUNCS 2
43#define GPIO_PER_REG 32
44
45/**
46 * struct armada_37xx_pin_group: represents group of pins of a pinmux function.
47 * The pins of a pinmux groups are composed of one or two groups of contiguous
48 * pins.
49 * @name: Name of the pin group, used to lookup the group.
50 * @start_pins: Index of the first pin of the main range of pins belonging to
51 * the group
52 * @npins: Number of pins included in the first range
53 * @reg_mask: Bit mask matching the group in the selection register
54 * @extra_pins: Index of the first pin of the optional second range of pins
55 * belonging to the group
56 * @npins: Number of pins included in the second optional range
57 * @funcs: A list of pinmux functions that can be selected for this group.
58 * @pins: List of the pins included in the group
59 */
60struct armada_37xx_pin_group {
61 const char *name;
62 unsigned int start_pin;
63 unsigned int npins;
64 u32 reg_mask;
65 u32 val[NB_FUNCS];
66 unsigned int extra_pin;
67 unsigned int extra_npins;
68 const char *funcs[NB_FUNCS];
69 unsigned int *pins;
70};
71
72struct armada_37xx_pin_data {
73 u8 nr_pins;
74 char *name;
75 struct armada_37xx_pin_group *groups;
76 int ngroups;
77};
78
79struct armada_37xx_pmx_func {
80 const char *name;
81 const char **groups;
82 unsigned int ngroups;
83};
84
85struct armada_37xx_pinctrl {
86 void __iomem *base;
87 const struct armada_37xx_pin_data *data;
88 struct udevice *dev;
89 struct pinctrl_dev *pctl_dev;
90 struct armada_37xx_pin_group *groups;
91 unsigned int ngroups;
92 struct armada_37xx_pmx_func *funcs;
93 unsigned int nfuncs;
94};
95
96#define PIN_GRP(_name, _start, _nr, _mask, _func1, _func2) \
97 { \
98 .name = _name, \
99 .start_pin = _start, \
100 .npins = _nr, \
101 .reg_mask = _mask, \
102 .val = {0, _mask}, \
103 .funcs = {_func1, _func2} \
104 }
105
106#define PIN_GRP_GPIO(_name, _start, _nr, _mask, _func1) \
107 { \
108 .name = _name, \
109 .start_pin = _start, \
110 .npins = _nr, \
111 .reg_mask = _mask, \
112 .val = {0, _mask}, \
113 .funcs = {_func1, "gpio"} \
114 }
115
116#define PIN_GRP_GPIO_2(_name, _start, _nr, _mask, _val1, _val2, _func1) \
117 { \
118 .name = _name, \
119 .start_pin = _start, \
120 .npins = _nr, \
121 .reg_mask = _mask, \
122 .val = {_val1, _val2}, \
123 .funcs = {_func1, "gpio"} \
124 }
125
126#define PIN_GRP_EXTRA(_name, _start, _nr, _mask, _v1, _v2, _start2, _nr2, \
127 _f1, _f2) \
128 { \
129 .name = _name, \
130 .start_pin = _start, \
131 .npins = _nr, \
132 .reg_mask = _mask, \
133 .val = {_v1, _v2}, \
134 .extra_pin = _start2, \
135 .extra_npins = _nr2, \
136 .funcs = {_f1, _f2} \
137 }
138
139static struct armada_37xx_pin_group armada_37xx_nb_groups[] = {
140 PIN_GRP_GPIO("jtag", 20, 5, BIT(0), "jtag"),
141 PIN_GRP_GPIO("sdio0", 8, 3, BIT(1), "sdio"),
142 PIN_GRP_GPIO("emmc_nb", 27, 9, BIT(2), "emmc"),
143 PIN_GRP_GPIO("pwm0", 11, 1, BIT(3), "pwm"),
144 PIN_GRP_GPIO("pwm1", 12, 1, BIT(4), "pwm"),
145 PIN_GRP_GPIO("pwm2", 13, 1, BIT(5), "pwm"),
146 PIN_GRP_GPIO("pwm3", 14, 1, BIT(6), "pwm"),
147 PIN_GRP_GPIO("pmic1", 17, 1, BIT(7), "pmic"),
148 PIN_GRP_GPIO("pmic0", 16, 1, BIT(8), "pmic"),
149 PIN_GRP_GPIO("i2c2", 2, 2, BIT(9), "i2c"),
150 PIN_GRP_GPIO("i2c1", 0, 2, BIT(10), "i2c"),
151 PIN_GRP_GPIO("spi_cs1", 17, 1, BIT(12), "spi"),
152 PIN_GRP_GPIO_2("spi_cs2", 18, 1, BIT(13) | BIT(19), 0, BIT(13), "spi"),
153 PIN_GRP_GPIO_2("spi_cs3", 19, 1, BIT(14) | BIT(19), 0, BIT(14), "spi"),
154 PIN_GRP_GPIO("onewire", 4, 1, BIT(16), "onewire"),
155 PIN_GRP_GPIO("uart1", 25, 2, BIT(17), "uart"),
156 PIN_GRP_GPIO("spi_quad", 15, 2, BIT(18), "spi"),
157 PIN_GRP_EXTRA("uart2", 9, 2, BIT(13) | BIT(14) | BIT(19),
158 BIT(13) | BIT(14), BIT(19), 18, 2, "gpio", "uart"),
159 PIN_GRP_GPIO("led0_od", 11, 1, BIT(20), "led"),
160 PIN_GRP_GPIO("led1_od", 12, 1, BIT(21), "led"),
161 PIN_GRP_GPIO("led2_od", 13, 1, BIT(22), "led"),
162 PIN_GRP_GPIO("led3_od", 14, 1, BIT(23), "led"),
163
164};
165
166static struct armada_37xx_pin_group armada_37xx_sb_groups[] = {
167 PIN_GRP_GPIO("usb32_drvvbus0", 0, 1, BIT(0), "drvbus"),
168 PIN_GRP_GPIO("usb2_drvvbus1", 1, 1, BIT(1), "drvbus"),
169 PIN_GRP_GPIO("sdio_sb", 24, 5, BIT(2), "sdio"),
170 PIN_GRP_EXTRA("rgmii", 6, 14, BIT(3), 0, BIT(3), 23, 1, "mii", "gpio"),
171 PIN_GRP_GPIO("pcie1", 3, 2, BIT(4), "pcie"),
172 PIN_GRP_GPIO("ptp", 20, 3, BIT(5), "ptp"),
173 PIN_GRP("ptp_clk", 21, 1, BIT(6), "ptp", "mii"),
174 PIN_GRP("ptp_trig", 22, 1, BIT(7), "ptp", "mii"),
175 PIN_GRP("mii_col", 23, 1, BIT(8), "mii", "mii_err"),
176};
177
178const struct armada_37xx_pin_data armada_37xx_pin_nb = {
179 .nr_pins = 36,
180 .name = "GPIO1",
181 .groups = armada_37xx_nb_groups,
182 .ngroups = ARRAY_SIZE(armada_37xx_nb_groups),
183};
184
185const struct armada_37xx_pin_data armada_37xx_pin_sb = {
186 .nr_pins = 29,
187 .name = "GPIO2",
188 .groups = armada_37xx_sb_groups,
189 .ngroups = ARRAY_SIZE(armada_37xx_sb_groups),
190};
191
192static int armada_37xx_get_func_reg(struct armada_37xx_pin_group *grp,
193 const char *func)
194{
195 int f;
196
197 for (f = 0; f < NB_FUNCS; f++)
198 if (!strcmp(grp->funcs[f], func))
199 return f;
200
201 return -ENOTSUPP;
202}
203
204static int armada_37xx_pmx_get_groups_count(struct udevice *dev)
205{
206 struct armada_37xx_pinctrl *info = dev_get_priv(dev);
207
208 return info->ngroups;
209}
210
211static const char *armada_37xx_pmx_dummy_name = "_dummy";
212
213static const char *armada_37xx_pmx_get_group_name(struct udevice *dev,
214 unsigned selector)
215{
216 struct armada_37xx_pinctrl *info = dev_get_priv(dev);
217
218 if (!info->groups[selector].name)
219 return armada_37xx_pmx_dummy_name;
220
221 return info->groups[selector].name;
222}
223
224static int armada_37xx_pmx_get_funcs_count(struct udevice *dev)
225{
226 struct armada_37xx_pinctrl *info = dev_get_priv(dev);
227
228 return info->nfuncs;
229}
230
231static const char *armada_37xx_pmx_get_func_name(struct udevice *dev,
232 unsigned selector)
233{
234 struct armada_37xx_pinctrl *info = dev_get_priv(dev);
235
236 return info->funcs[selector].name;
237}
238
239static int armada_37xx_pmx_set_by_name(struct udevice *dev,
240 const char *name,
241 struct armada_37xx_pin_group *grp)
242{
243 struct armada_37xx_pinctrl *info = dev_get_priv(dev);
244 unsigned int reg = SELECTION;
245 unsigned int mask = grp->reg_mask;
246 int func, val;
247
248 dev_dbg(info->dev, "enable function %s group %s\n",
249 name, grp->name);
250
251 func = armada_37xx_get_func_reg(grp, name);
252
253 if (func < 0)
254 return func;
255
256 val = grp->val[func];
257
258 clrsetbits_le32(info->base + reg, mask, val);
259
260 return 0;
261}
262
263static int armada_37xx_pmx_group_set(struct udevice *dev,
264 unsigned group_selector,
265 unsigned func_selector)
266{
267 struct armada_37xx_pinctrl *info = dev_get_priv(dev);
268 struct armada_37xx_pin_group *grp = &info->groups[group_selector];
269 const char *name = info->funcs[func_selector].name;
270
271 return armada_37xx_pmx_set_by_name(dev, name, grp);
272}
273
274/**
275 * armada_37xx_add_function() - Add a new function to the list
276 * @funcs: array of function to add the new one
277 * @funcsize: size of the remaining space for the function
278 * @name: name of the function to add
279 *
280 * If it is a new function then create it by adding its name else
281 * increment the number of group associated to this function.
282 */
283static int armada_37xx_add_function(struct armada_37xx_pmx_func *funcs,
284 int *funcsize, const char *name)
285{
286 int i = 0;
287
288 if (*funcsize <= 0)
289 return -EOVERFLOW;
290
291 while (funcs->ngroups) {
292 /* function already there */
293 if (strcmp(funcs->name, name) == 0) {
294 funcs->ngroups++;
295
296 return -EEXIST;
297 }
298 funcs++;
299 i++;
300 }
301
302 /* append new unique function */
303 funcs->name = name;
304 funcs->ngroups = 1;
305 (*funcsize)--;
306
307 return 0;
308}
309
310/**
311 * armada_37xx_fill_group() - complete the group array
312 * @info: info driver instance
313 *
314 * Based on the data available from the armada_37xx_pin_group array
315 * completes the last member of the struct for each function: the list
316 * of the groups associated to this function.
317 *
318 */
319static int armada_37xx_fill_group(struct armada_37xx_pinctrl *info)
320{
321 int n, num = 0, funcsize = info->data->nr_pins;
322
323 for (n = 0; n < info->ngroups; n++) {
324 struct armada_37xx_pin_group *grp = &info->groups[n];
325 int i, j, f;
326
327 grp->pins = devm_kzalloc(info->dev,
328 (grp->npins + grp->extra_npins) *
329 sizeof(*grp->pins), GFP_KERNEL);
330 if (!grp->pins)
331 return -ENOMEM;
332
333 for (i = 0; i < grp->npins; i++)
334 grp->pins[i] = grp->start_pin + i;
335
336 for (j = 0; j < grp->extra_npins; j++)
337 grp->pins[i+j] = grp->extra_pin + j;
338
339 for (f = 0; f < NB_FUNCS; f++) {
340 int ret;
341 /* check for unique functions and count groups */
342 ret = armada_37xx_add_function(info->funcs, &funcsize,
343 grp->funcs[f]);
344 if (ret == -EOVERFLOW)
345 dev_err(info->dev,
346 "More functions than pins(%d)\n",
347 info->data->nr_pins);
348 if (ret < 0)
349 continue;
350 num++;
351 }
352 }
353
354 info->nfuncs = num;
355
356 return 0;
357}
358
359/**
360 * armada_37xx_fill_funcs() - complete the funcs array
361 * @info: info driver instance
362 *
363 * Based on the data available from the armada_37xx_pin_group array
364 * completes the last two member of the struct for each group:
365 * - the list of the pins included in the group
366 * - the list of pinmux functions that can be selected for this group
367 *
368 */
369static int armada_37xx_fill_func(struct armada_37xx_pinctrl *info)
370{
371 struct armada_37xx_pmx_func *funcs = info->funcs;
372 int n;
373
374 for (n = 0; n < info->nfuncs; n++) {
375 const char *name = funcs[n].name;
376 const char **groups;
377 int g;
378
379 funcs[n].groups = devm_kzalloc(info->dev, funcs[n].ngroups *
380 sizeof(*(funcs[n].groups)),
381 GFP_KERNEL);
382 if (!funcs[n].groups)
383 return -ENOMEM;
384
385 groups = funcs[n].groups;
386
387 for (g = 0; g < info->ngroups; g++) {
388 struct armada_37xx_pin_group *gp = &info->groups[g];
389 int f;
390
391 for (f = 0; f < NB_FUNCS; f++) {
392 if (strcmp(gp->funcs[f], name) == 0) {
393 *groups = gp->name;
394 groups++;
395 }
396 }
397 }
398 }
399 return 0;
400}
401
402const struct pinctrl_ops armada_37xx_pinctrl_ops = {
403 .get_groups_count = armada_37xx_pmx_get_groups_count,
404 .get_group_name = armada_37xx_pmx_get_group_name,
405 .get_functions_count = armada_37xx_pmx_get_funcs_count,
406 .get_function_name = armada_37xx_pmx_get_func_name,
407 .pinmux_group_set = armada_37xx_pmx_group_set,
408 .set_state = pinctrl_generic_set_state,
409};
410
411int armada_37xx_pinctrl_probe(struct udevice *dev)
412{
413 struct armada_37xx_pinctrl *info = dev_get_priv(dev);
414 const struct armada_37xx_pin_data *pin_data;
415 int ret;
416
417 info->data = (struct armada_37xx_pin_data *)dev_get_driver_data(dev);
418 pin_data = info->data;
419
420 info->base = (void __iomem *)dev_get_addr(dev);
421 if (!info->base) {
422 error("unable to find regmap\n");
423 return -ENODEV;
424 }
425
426 info->groups = pin_data->groups;
427 info->ngroups = pin_data->ngroups;
428
429 /*
430 * we allocate functions for number of pins and hope there are
431 * fewer unique functions than pins available
432 */
433 info->funcs = devm_kzalloc(info->dev, pin_data->nr_pins *
434 sizeof(struct armada_37xx_pmx_func), GFP_KERNEL);
435 if (!info->funcs)
436 return -ENOMEM;
437
438
439 ret = armada_37xx_fill_group(info);
440 if (ret)
441 return ret;
442
443 ret = armada_37xx_fill_func(info);
444 if (ret)
445 return ret;
446
447 return 0;
448}
449
450static const struct udevice_id armada_37xx_pinctrl_of_match[] = {
451 {
452 .compatible = "marvell,armada3710-sb-pinctrl",
453 .data = (ulong)&armada_37xx_pin_sb,
454 },
455 {
456 .compatible = "marvell,armada3710-nb-pinctrl",
457 .data = (ulong)&armada_37xx_pin_nb,
458 },
459 { /* sentinel */ }
460};
461
462U_BOOT_DRIVER(armada_37xx_pinctrl) = {
463 .name = "armada-37xx-pinctrl",
464 .id = UCLASS_PINCTRL,
465 .of_match = of_match_ptr(armada_37xx_pinctrl_of_match),
466 .probe = armada_37xx_pinctrl_probe,
467 .priv_auto_alloc_size = sizeof(struct armada_37xx_pinctrl),
468 .ops = &armada_37xx_pinctrl_ops,
469};