diff options
author | Andrew Jeffery <andrew@aj.id.au> | 2016-08-30 03:54:24 -0400 |
---|---|---|
committer | Linus Walleij <linus.walleij@linaro.org> | 2016-09-07 10:48:22 -0400 |
commit | 4d3d0e4272d8d660f5f14f5abcf96fb4df1aa94b (patch) | |
tree | a4722451117ba7c65f2c766c67c7998faac0fdac | |
parent | 5f714700b1892f8d67495567f16c63ad7b20d6b3 (diff) |
pinctrl: Add core support for Aspeed SoCs
The Aspeed SoCs typically provide more than 200 pins for GPIO and other
functions. The signal enabled on a pin is determined on a priority
basis, where a given pin can provide a number of different signal types.
In addition to the priority levels, the Aspeed pin controllers describe
the signal active on a pin by compound logical expressions involving
multiple operators, registers and bits. Some difficulty arises as a
pin's function bit masks for each priority level are frequently not the
same (i.e. we cannot just flip a bit to change from a high to low
priority signal), or even in the same register(s). Some configuration
bits affect multiple pins, while in other cases the signals for a bus
must each be enabled individually.
Together, these features give rise to some complexity in the
implementation. A more complete description of the complexities is
provided in the associated header file.
The patch doesn't implement pinctrl/pinmux/pinconf for any particular
Aspeed SoC, rather it adds the framework for defining pinmux
configurations.
Signed-off-by: Andrew Jeffery <andrew@aj.id.au>
Reviewed-by: Joel Stanley <joel@jms.id.au>
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
-rw-r--r-- | drivers/pinctrl/Kconfig | 1 | ||||
-rw-r--r-- | drivers/pinctrl/Makefile | 1 | ||||
-rw-r--r-- | drivers/pinctrl/aspeed/Kconfig | 8 | ||||
-rw-r--r-- | drivers/pinctrl/aspeed/Makefile | 4 | ||||
-rw-r--r-- | drivers/pinctrl/aspeed/pinctrl-aspeed.c | 498 | ||||
-rw-r--r-- | drivers/pinctrl/aspeed/pinctrl-aspeed.h | 569 |
6 files changed, 1081 insertions, 0 deletions
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index b3fe1d339632..0e75d94972ba 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig | |||
@@ -254,6 +254,7 @@ config PINCTRL_ZYNQ | |||
254 | help | 254 | help |
255 | This selects the pinctrl driver for Xilinx Zynq. | 255 | This selects the pinctrl driver for Xilinx Zynq. |
256 | 256 | ||
257 | source "drivers/pinctrl/aspeed/Kconfig" | ||
257 | source "drivers/pinctrl/bcm/Kconfig" | 258 | source "drivers/pinctrl/bcm/Kconfig" |
258 | source "drivers/pinctrl/berlin/Kconfig" | 259 | source "drivers/pinctrl/berlin/Kconfig" |
259 | source "drivers/pinctrl/freescale/Kconfig" | 260 | source "drivers/pinctrl/freescale/Kconfig" |
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index 8ebd7b8e1621..11bad373dfe0 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile | |||
@@ -37,6 +37,7 @@ obj-$(CONFIG_PINCTRL_TB10X) += pinctrl-tb10x.o | |||
37 | obj-$(CONFIG_PINCTRL_ST) += pinctrl-st.o | 37 | obj-$(CONFIG_PINCTRL_ST) += pinctrl-st.o |
38 | obj-$(CONFIG_PINCTRL_ZYNQ) += pinctrl-zynq.o | 38 | obj-$(CONFIG_PINCTRL_ZYNQ) += pinctrl-zynq.o |
39 | 39 | ||
40 | obj-$(CONFIG_ARCH_ASPEED) += aspeed/ | ||
40 | obj-y += bcm/ | 41 | obj-y += bcm/ |
41 | obj-$(CONFIG_PINCTRL_BERLIN) += berlin/ | 42 | obj-$(CONFIG_PINCTRL_BERLIN) += berlin/ |
42 | obj-y += freescale/ | 43 | obj-y += freescale/ |
diff --git a/drivers/pinctrl/aspeed/Kconfig b/drivers/pinctrl/aspeed/Kconfig new file mode 100644 index 000000000000..757002f9be30 --- /dev/null +++ b/drivers/pinctrl/aspeed/Kconfig | |||
@@ -0,0 +1,8 @@ | |||
1 | config PINCTRL_ASPEED | ||
2 | bool | ||
3 | depends on (ARCH_ASPEED || COMPILE_TEST) && OF | ||
4 | depends on MFD_SYSCON | ||
5 | select PINMUX | ||
6 | select PINCONF | ||
7 | select GENERIC_PINCONF | ||
8 | select REGMAP_MMIO | ||
diff --git a/drivers/pinctrl/aspeed/Makefile b/drivers/pinctrl/aspeed/Makefile new file mode 100644 index 000000000000..a0fc61d31ccf --- /dev/null +++ b/drivers/pinctrl/aspeed/Makefile | |||
@@ -0,0 +1,4 @@ | |||
1 | # Aspeed pinctrl support | ||
2 | |||
3 | ccflags-y += -Woverride-init | ||
4 | obj-$(CONFIG_PINCTRL_ASPEED) += pinctrl-aspeed.o | ||
diff --git a/drivers/pinctrl/aspeed/pinctrl-aspeed.c b/drivers/pinctrl/aspeed/pinctrl-aspeed.c new file mode 100644 index 000000000000..7d461fc30d3c --- /dev/null +++ b/drivers/pinctrl/aspeed/pinctrl-aspeed.c | |||
@@ -0,0 +1,498 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2016 IBM Corp. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | */ | ||
9 | |||
10 | #include <linux/mfd/syscon.h> | ||
11 | #include <linux/platform_device.h> | ||
12 | #include <linux/slab.h> | ||
13 | #include <linux/string.h> | ||
14 | #include "../core.h" | ||
15 | #include "pinctrl-aspeed.h" | ||
16 | |||
17 | int aspeed_pinctrl_get_groups_count(struct pinctrl_dev *pctldev) | ||
18 | { | ||
19 | struct aspeed_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev); | ||
20 | |||
21 | return pdata->ngroups; | ||
22 | } | ||
23 | |||
24 | const char *aspeed_pinctrl_get_group_name(struct pinctrl_dev *pctldev, | ||
25 | unsigned int group) | ||
26 | { | ||
27 | struct aspeed_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev); | ||
28 | |||
29 | return pdata->groups[group].name; | ||
30 | } | ||
31 | |||
32 | int aspeed_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, | ||
33 | unsigned int group, const unsigned int **pins, | ||
34 | unsigned int *npins) | ||
35 | { | ||
36 | struct aspeed_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev); | ||
37 | |||
38 | *pins = &pdata->groups[group].pins[0]; | ||
39 | *npins = pdata->groups[group].npins; | ||
40 | |||
41 | return 0; | ||
42 | } | ||
43 | |||
44 | void aspeed_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev, | ||
45 | struct seq_file *s, unsigned int offset) | ||
46 | { | ||
47 | seq_printf(s, " %s", dev_name(pctldev->dev)); | ||
48 | } | ||
49 | |||
50 | int aspeed_pinmux_get_fn_count(struct pinctrl_dev *pctldev) | ||
51 | { | ||
52 | struct aspeed_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev); | ||
53 | |||
54 | return pdata->nfunctions; | ||
55 | } | ||
56 | |||
57 | const char *aspeed_pinmux_get_fn_name(struct pinctrl_dev *pctldev, | ||
58 | unsigned int function) | ||
59 | { | ||
60 | struct aspeed_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev); | ||
61 | |||
62 | return pdata->functions[function].name; | ||
63 | } | ||
64 | |||
65 | int aspeed_pinmux_get_fn_groups(struct pinctrl_dev *pctldev, | ||
66 | unsigned int function, | ||
67 | const char * const **groups, | ||
68 | unsigned int * const num_groups) | ||
69 | { | ||
70 | struct aspeed_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev); | ||
71 | |||
72 | *groups = pdata->functions[function].groups; | ||
73 | *num_groups = pdata->functions[function].ngroups; | ||
74 | |||
75 | return 0; | ||
76 | } | ||
77 | |||
78 | static inline void aspeed_sig_desc_print_val( | ||
79 | const struct aspeed_sig_desc *desc, bool enable, u32 rv) | ||
80 | { | ||
81 | pr_debug("SCU%x[0x%08x]=0x%x, got 0x%x from 0x%08x\n", desc->reg, | ||
82 | desc->mask, enable ? desc->enable : desc->disable, | ||
83 | (rv & desc->mask) >> __ffs(desc->mask), rv); | ||
84 | } | ||
85 | |||
86 | /** | ||
87 | * Query the enabled or disabled state of a signal descriptor | ||
88 | * | ||
89 | * @desc: The signal descriptor of interest | ||
90 | * @enabled: True to query the enabled state, false to query disabled state | ||
91 | * @regmap: The SCU regmap instance | ||
92 | * | ||
93 | * @return True if the descriptor's bitfield is configured to the state | ||
94 | * selected by @enabled, false otherwise | ||
95 | * | ||
96 | * Evaluation of descriptor state is non-trivial in that it is not a binary | ||
97 | * outcome: The bitfields can be greater than one bit in size and thus can take | ||
98 | * a value that is neither the enabled nor disabled state recorded in the | ||
99 | * descriptor (typically this means a different function to the one of interest | ||
100 | * is enabled). Thus we must explicitly test for either condition as required. | ||
101 | */ | ||
102 | static bool aspeed_sig_desc_eval(const struct aspeed_sig_desc *desc, | ||
103 | bool enabled, struct regmap *map) | ||
104 | { | ||
105 | unsigned int raw; | ||
106 | u32 want; | ||
107 | |||
108 | if (regmap_read(map, desc->reg, &raw) < 0) | ||
109 | return false; | ||
110 | |||
111 | aspeed_sig_desc_print_val(desc, enabled, raw); | ||
112 | want = enabled ? desc->enable : desc->disable; | ||
113 | |||
114 | return ((raw & desc->mask) >> __ffs(desc->mask)) == want; | ||
115 | } | ||
116 | |||
117 | /** | ||
118 | * Query the enabled or disabled state for a mux function's signal on a pin | ||
119 | * | ||
120 | * @expr: An expression controlling the signal for a mux function on a pin | ||
121 | * @enabled: True to query the enabled state, false to query disabled state | ||
122 | * @regmap: The SCU regmap instance | ||
123 | * | ||
124 | * @return True if the expression composed by @enabled evaluates true, false | ||
125 | * otherwise | ||
126 | * | ||
127 | * A mux function is enabled or disabled if the function's signal expression | ||
128 | * for each pin in the function's pin group evaluates true for the desired | ||
129 | * state. An signal expression evaluates true if all of its associated signal | ||
130 | * descriptors evaluate true for the desired state. | ||
131 | * | ||
132 | * If an expression's state is described by more than one bit, either through | ||
133 | * multi-bit bitfields in a single signal descriptor or through multiple signal | ||
134 | * descriptors of a single bit then it is possible for the expression to be in | ||
135 | * neither the enabled nor disabled state. Thus we must explicitly test for | ||
136 | * either condition as required. | ||
137 | */ | ||
138 | static bool aspeed_sig_expr_eval(const struct aspeed_sig_expr *expr, | ||
139 | bool enabled, struct regmap *map) | ||
140 | { | ||
141 | int i; | ||
142 | |||
143 | for (i = 0; i < expr->ndescs; i++) { | ||
144 | const struct aspeed_sig_desc *desc = &expr->descs[i]; | ||
145 | |||
146 | if (!aspeed_sig_desc_eval(desc, enabled, map)) | ||
147 | return false; | ||
148 | } | ||
149 | |||
150 | return true; | ||
151 | } | ||
152 | |||
153 | /** | ||
154 | * Configure a pin's signal by applying an expression's descriptor state for | ||
155 | * all descriptors in the expression. | ||
156 | * | ||
157 | * @expr: The expression associated with the function whose signal is to be | ||
158 | * configured | ||
159 | * @enable: true to enable an function's signal through a pin's signal | ||
160 | * expression, false to disable the function's signal | ||
161 | * @map: The SCU's regmap instance for pinmux register access. | ||
162 | * | ||
163 | * @return true if the expression is configured as requested, false otherwise | ||
164 | */ | ||
165 | static bool aspeed_sig_expr_set(const struct aspeed_sig_expr *expr, | ||
166 | bool enable, struct regmap *map) | ||
167 | { | ||
168 | int i; | ||
169 | bool ret; | ||
170 | |||
171 | ret = aspeed_sig_expr_eval(expr, enable, map); | ||
172 | if (ret) | ||
173 | return ret; | ||
174 | |||
175 | for (i = 0; i < expr->ndescs; i++) { | ||
176 | const struct aspeed_sig_desc *desc = &expr->descs[i]; | ||
177 | u32 pattern = enable ? desc->enable : desc->disable; | ||
178 | |||
179 | /* | ||
180 | * Strap registers are configured in hardware or by early-boot | ||
181 | * firmware. Treat them as read-only despite that we can write | ||
182 | * them. This may mean that certain functions cannot be | ||
183 | * deconfigured and is the reason we re-evaluate after writing | ||
184 | * all descriptor bits. | ||
185 | */ | ||
186 | if (desc->reg == HW_STRAP1 || desc->reg == HW_STRAP2) | ||
187 | continue; | ||
188 | |||
189 | ret = regmap_update_bits(map, desc->reg, desc->mask, | ||
190 | pattern << __ffs(desc->mask)); | ||
191 | |||
192 | if (ret < 0) | ||
193 | return false; | ||
194 | } | ||
195 | |||
196 | return aspeed_sig_expr_eval(expr, enable, map); | ||
197 | } | ||
198 | |||
199 | static bool aspeed_sig_expr_enable(const struct aspeed_sig_expr *expr, | ||
200 | struct regmap *map) | ||
201 | { | ||
202 | return aspeed_sig_expr_set(expr, true, map); | ||
203 | } | ||
204 | |||
205 | static bool aspeed_sig_expr_disable(const struct aspeed_sig_expr *expr, | ||
206 | struct regmap *map) | ||
207 | { | ||
208 | return aspeed_sig_expr_set(expr, false, map); | ||
209 | } | ||
210 | |||
211 | /** | ||
212 | * Disable a signal on a pin by disabling all provided signal expressions. | ||
213 | * | ||
214 | * @exprs: The list of signal expressions (from a priority level on a pin) | ||
215 | * @map: The SCU's regmap instance for pinmux register access. | ||
216 | * | ||
217 | * @return true if all expressions in the list are successfully disabled, false | ||
218 | * otherwise | ||
219 | */ | ||
220 | static bool aspeed_disable_sig(const struct aspeed_sig_expr **exprs, | ||
221 | struct regmap *map) | ||
222 | { | ||
223 | bool disabled = true; | ||
224 | |||
225 | if (!exprs) | ||
226 | return true; | ||
227 | |||
228 | while (*exprs) { | ||
229 | bool ret; | ||
230 | |||
231 | ret = aspeed_sig_expr_disable(*exprs, map); | ||
232 | disabled = disabled && ret; | ||
233 | |||
234 | exprs++; | ||
235 | } | ||
236 | |||
237 | return disabled; | ||
238 | } | ||
239 | |||
240 | /** | ||
241 | * Search for the signal expression needed to enable the pin's signal for the | ||
242 | * requested function. | ||
243 | * | ||
244 | * @exprs: List of signal expressions (haystack) | ||
245 | * @name: The name of the requested function (needle) | ||
246 | * | ||
247 | * @return A pointer to the signal expression whose function tag matches the | ||
248 | * provided name, otherwise NULL. | ||
249 | * | ||
250 | */ | ||
251 | static const struct aspeed_sig_expr *aspeed_find_expr_by_name( | ||
252 | const struct aspeed_sig_expr **exprs, const char *name) | ||
253 | { | ||
254 | while (*exprs) { | ||
255 | if (strcmp((*exprs)->function, name) == 0) | ||
256 | return *exprs; | ||
257 | exprs++; | ||
258 | } | ||
259 | |||
260 | return NULL; | ||
261 | } | ||
262 | |||
263 | static char *get_defined_attribute(const struct aspeed_pin_desc *pdesc, | ||
264 | const char *(*get)( | ||
265 | const struct aspeed_sig_expr *)) | ||
266 | { | ||
267 | char *found = NULL; | ||
268 | size_t len = 0; | ||
269 | const struct aspeed_sig_expr ***prios, **funcs, *expr; | ||
270 | |||
271 | prios = pdesc->prios; | ||
272 | |||
273 | while ((funcs = *prios)) { | ||
274 | while ((expr = *funcs)) { | ||
275 | const char *str = get(expr); | ||
276 | size_t delta = strlen(str) + 2; | ||
277 | char *expanded; | ||
278 | |||
279 | expanded = krealloc(found, len + delta + 1, GFP_KERNEL); | ||
280 | if (!expanded) { | ||
281 | kfree(found); | ||
282 | return expanded; | ||
283 | } | ||
284 | |||
285 | found = expanded; | ||
286 | found[len] = '\0'; | ||
287 | len += delta; | ||
288 | |||
289 | strcat(found, str); | ||
290 | strcat(found, ", "); | ||
291 | |||
292 | funcs++; | ||
293 | } | ||
294 | prios++; | ||
295 | } | ||
296 | |||
297 | if (len < 2) { | ||
298 | kfree(found); | ||
299 | return NULL; | ||
300 | } | ||
301 | |||
302 | found[len - 2] = '\0'; | ||
303 | |||
304 | return found; | ||
305 | } | ||
306 | |||
307 | static const char *aspeed_sig_expr_function(const struct aspeed_sig_expr *expr) | ||
308 | { | ||
309 | return expr->function; | ||
310 | } | ||
311 | |||
312 | static char *get_defined_functions(const struct aspeed_pin_desc *pdesc) | ||
313 | { | ||
314 | return get_defined_attribute(pdesc, aspeed_sig_expr_function); | ||
315 | } | ||
316 | |||
317 | static const char *aspeed_sig_expr_signal(const struct aspeed_sig_expr *expr) | ||
318 | { | ||
319 | return expr->signal; | ||
320 | } | ||
321 | |||
322 | static char *get_defined_signals(const struct aspeed_pin_desc *pdesc) | ||
323 | { | ||
324 | return get_defined_attribute(pdesc, aspeed_sig_expr_signal); | ||
325 | } | ||
326 | |||
327 | int aspeed_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned int function, | ||
328 | unsigned int group) | ||
329 | { | ||
330 | int i; | ||
331 | const struct aspeed_pinctrl_data *pdata = | ||
332 | pinctrl_dev_get_drvdata(pctldev); | ||
333 | const struct aspeed_pin_group *pgroup = &pdata->groups[group]; | ||
334 | const struct aspeed_pin_function *pfunc = | ||
335 | &pdata->functions[function]; | ||
336 | |||
337 | for (i = 0; i < pgroup->npins; i++) { | ||
338 | int pin = pgroup->pins[i]; | ||
339 | const struct aspeed_pin_desc *pdesc = pdata->pins[pin].drv_data; | ||
340 | const struct aspeed_sig_expr *expr = NULL; | ||
341 | const struct aspeed_sig_expr **funcs; | ||
342 | const struct aspeed_sig_expr ***prios; | ||
343 | |||
344 | if (!pdesc) | ||
345 | return -EINVAL; | ||
346 | |||
347 | prios = pdesc->prios; | ||
348 | |||
349 | if (!prios) | ||
350 | continue; | ||
351 | |||
352 | /* Disable functions at a higher priority than that requested */ | ||
353 | while ((funcs = *prios)) { | ||
354 | expr = aspeed_find_expr_by_name(funcs, pfunc->name); | ||
355 | |||
356 | if (expr) | ||
357 | break; | ||
358 | |||
359 | if (!aspeed_disable_sig(funcs, pdata->map)) | ||
360 | return -EPERM; | ||
361 | |||
362 | prios++; | ||
363 | } | ||
364 | |||
365 | if (!expr) { | ||
366 | char *functions = get_defined_functions(pdesc); | ||
367 | char *signals = get_defined_signals(pdesc); | ||
368 | |||
369 | pr_warn("No function %s found on pin %s (%d). Found signal(s) %s for function(s) %s\n", | ||
370 | pfunc->name, pdesc->name, pin, signals, | ||
371 | functions); | ||
372 | kfree(signals); | ||
373 | kfree(functions); | ||
374 | |||
375 | return -ENXIO; | ||
376 | } | ||
377 | |||
378 | if (!aspeed_sig_expr_enable(expr, pdata->map)) | ||
379 | return -EPERM; | ||
380 | } | ||
381 | |||
382 | return 0; | ||
383 | } | ||
384 | |||
385 | static bool aspeed_expr_is_gpio(const struct aspeed_sig_expr *expr) | ||
386 | { | ||
387 | /* | ||
388 | * The signal type is GPIO if the signal name has "GPIO" as a prefix. | ||
389 | * strncmp (rather than strcmp) is used to implement the prefix | ||
390 | * requirement. | ||
391 | * | ||
392 | * expr->signal might look like "GPIOT3" in the GPIO case. | ||
393 | */ | ||
394 | return strncmp(expr->signal, "GPIO", 4) == 0; | ||
395 | } | ||
396 | |||
397 | static bool aspeed_gpio_in_exprs(const struct aspeed_sig_expr **exprs) | ||
398 | { | ||
399 | if (!exprs) | ||
400 | return false; | ||
401 | |||
402 | while (*exprs) { | ||
403 | if (aspeed_expr_is_gpio(*exprs)) | ||
404 | return true; | ||
405 | exprs++; | ||
406 | } | ||
407 | |||
408 | return false; | ||
409 | } | ||
410 | |||
411 | int aspeed_gpio_request_enable(struct pinctrl_dev *pctldev, | ||
412 | struct pinctrl_gpio_range *range, | ||
413 | unsigned int offset) | ||
414 | { | ||
415 | const struct aspeed_pinctrl_data *pdata = | ||
416 | pinctrl_dev_get_drvdata(pctldev); | ||
417 | const struct aspeed_pin_desc *pdesc = pdata->pins[offset].drv_data; | ||
418 | const struct aspeed_sig_expr ***prios, **funcs, *expr; | ||
419 | |||
420 | if (!pdesc) | ||
421 | return -EINVAL; | ||
422 | |||
423 | prios = pdesc->prios; | ||
424 | |||
425 | if (!prios) | ||
426 | return -ENXIO; | ||
427 | |||
428 | /* Disable any functions of higher priority than GPIO */ | ||
429 | while ((funcs = *prios)) { | ||
430 | if (aspeed_gpio_in_exprs(funcs)) | ||
431 | break; | ||
432 | |||
433 | if (!aspeed_disable_sig(funcs, pdata->map)) | ||
434 | return -EPERM; | ||
435 | |||
436 | prios++; | ||
437 | } | ||
438 | |||
439 | if (!funcs) { | ||
440 | char *signals = get_defined_signals(pdesc); | ||
441 | |||
442 | pr_warn("No GPIO signal type found on pin %s (%d). Found: %s\n", | ||
443 | pdesc->name, offset, signals); | ||
444 | kfree(signals); | ||
445 | |||
446 | return -ENXIO; | ||
447 | } | ||
448 | |||
449 | expr = *funcs; | ||
450 | |||
451 | /* | ||
452 | * Disabling all higher-priority expressions is enough to enable the | ||
453 | * lowest-priority signal type. As such it has no associated | ||
454 | * expression. | ||
455 | */ | ||
456 | if (!expr) | ||
457 | return 0; | ||
458 | |||
459 | /* | ||
460 | * If GPIO is not the lowest priority signal type, assume there is only | ||
461 | * one expression defined to enable the GPIO function | ||
462 | */ | ||
463 | if (!aspeed_sig_expr_enable(expr, pdata->map)) | ||
464 | return -EPERM; | ||
465 | |||
466 | return 0; | ||
467 | } | ||
468 | |||
469 | int aspeed_pinctrl_probe(struct platform_device *pdev, | ||
470 | struct pinctrl_desc *pdesc, | ||
471 | struct aspeed_pinctrl_data *pdata) | ||
472 | { | ||
473 | struct device *parent; | ||
474 | struct pinctrl_dev *pctl; | ||
475 | |||
476 | parent = pdev->dev.parent; | ||
477 | if (!parent) { | ||
478 | dev_err(&pdev->dev, "No parent for syscon pincontroller\n"); | ||
479 | return -ENODEV; | ||
480 | } | ||
481 | |||
482 | pdata->map = syscon_node_to_regmap(parent->of_node); | ||
483 | if (IS_ERR(pdata->map)) { | ||
484 | dev_err(&pdev->dev, "No regmap for syscon pincontroller parent\n"); | ||
485 | return PTR_ERR(pdata->map); | ||
486 | } | ||
487 | |||
488 | pctl = pinctrl_register(pdesc, &pdev->dev, pdata); | ||
489 | |||
490 | if (IS_ERR(pctl)) { | ||
491 | dev_err(&pdev->dev, "Failed to register pinctrl\n"); | ||
492 | return PTR_ERR(pctl); | ||
493 | } | ||
494 | |||
495 | platform_set_drvdata(pdev, pdata); | ||
496 | |||
497 | return 0; | ||
498 | } | ||
diff --git a/drivers/pinctrl/aspeed/pinctrl-aspeed.h b/drivers/pinctrl/aspeed/pinctrl-aspeed.h new file mode 100644 index 000000000000..3e72ef8c54bf --- /dev/null +++ b/drivers/pinctrl/aspeed/pinctrl-aspeed.h | |||
@@ -0,0 +1,569 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2016 IBM Corp. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | */ | ||
9 | |||
10 | #ifndef PINCTRL_ASPEED | ||
11 | #define PINCTRL_ASPEED | ||
12 | |||
13 | #include <linux/pinctrl/pinctrl.h> | ||
14 | #include <linux/pinctrl/pinmux.h> | ||
15 | #include <linux/pinctrl/pinconf.h> | ||
16 | #include <linux/pinctrl/pinconf-generic.h> | ||
17 | #include <linux/regmap.h> | ||
18 | |||
19 | /* | ||
20 | * The ASPEED SoCs provide typically more than 200 pins for GPIO and other | ||
21 | * functions. The SoC function enabled on a pin is determined on a priority | ||
22 | * basis where a given pin can provide a number of different signal types. | ||
23 | * | ||
24 | * The signal active on a pin is described by both a priority level and | ||
25 | * compound logical expressions involving multiple operators, registers and | ||
26 | * bits. Some difficulty arises as the pin's function bit masks for each | ||
27 | * priority level are frequently not the same (i.e. cannot just flip a bit to | ||
28 | * change from a high to low priority signal), or even in the same register. | ||
29 | * Further, not all signals can be unmuxed, as some expressions depend on | ||
30 | * values in the hardware strapping register (which is treated as read-only). | ||
31 | * | ||
32 | * SoC Multi-function Pin Expression Examples | ||
33 | * ------------------------------------------ | ||
34 | * | ||
35 | * Here are some sample mux configurations from the AST2400 and AST2500 | ||
36 | * datasheets to illustrate the corner cases, roughly in order of least to most | ||
37 | * corner. The signal priorities are in decending order from P0 (highest). | ||
38 | * | ||
39 | * D6 is a pin with a single function (beside GPIO); a high priority signal | ||
40 | * that participates in one function: | ||
41 | * | ||
42 | * Ball | Default | P0 Signal | P0 Expression | P1 Signal | P1 Expression | Other | ||
43 | * -----+---------+-----------+-----------------------------+-----------+---------------+---------- | ||
44 | * D6 GPIOA0 MAC1LINK SCU80[0]=1 GPIOA0 | ||
45 | * -----+---------+-----------+-----------------------------+-----------+---------------+---------- | ||
46 | * | ||
47 | * C5 is a multi-signal pin (high and low priority signals). Here we touch | ||
48 | * different registers for the different functions that enable each signal: | ||
49 | * | ||
50 | * -----+---------+-----------+-----------------------------+-----------+---------------+---------- | ||
51 | * C5 GPIOA4 SCL9 SCU90[22]=1 TIMER5 SCU80[4]=1 GPIOA4 | ||
52 | * -----+---------+-----------+-----------------------------+-----------+---------------+---------- | ||
53 | * | ||
54 | * E19 is a single-signal pin with two functions that influence the active | ||
55 | * signal. In this case both bits have the same meaning - enable a dedicated | ||
56 | * LPC reset pin. However it's not always the case that the bits in the | ||
57 | * OR-relationship have the same meaning. | ||
58 | * | ||
59 | * -----+---------+-----------+-----------------------------+-----------+---------------+---------- | ||
60 | * E19 GPIOB4 LPCRST# SCU80[12]=1 | Strap[14]=1 GPIOB4 | ||
61 | * -----+---------+-----------+-----------------------------+-----------+---------------+---------- | ||
62 | * | ||
63 | * For example, pin B19 has a low-priority signal that's enabled by two | ||
64 | * distinct SoC functions: A specific SIOPBI bit in register SCUA4, and an ACPI | ||
65 | * bit in the STRAP register. The ACPI bit configures signals on pins in | ||
66 | * addition to B19. Both of the low priority functions as well as the high | ||
67 | * priority function must be disabled for GPIOF1 to be used. | ||
68 | * | ||
69 | * Ball | Default | P0 Signal | P0 Expression | P1 Signal | P1 Expression | Other | ||
70 | * -----+---------+-----------+-----------------------------------------+-----------+----------------------------------------+---------- | ||
71 | * B19 GPIOF1 NDCD4 SCU80[25]=1 SIOPBI# SCUA4[12]=1 | Strap[19]=0 GPIOF1 | ||
72 | * -----+---------+-----------+-----------------------------------------+-----------+----------------------------------------+---------- | ||
73 | * | ||
74 | * For pin E18, the SoC ANDs the expected state of three bits to determine the | ||
75 | * pin's active signal: | ||
76 | * | ||
77 | * * SCU3C[3]: Enable external SOC reset function | ||
78 | * * SCU80[15]: Enable SPICS1# or EXTRST# function pin | ||
79 | * * SCU90[31]: Select SPI interface CS# output | ||
80 | * | ||
81 | * -----+---------+-----------+-----------------------------------------+-----------+----------------------------------------+---------- | ||
82 | * E18 GPIOB7 EXTRST# SCU3C[3]=1 & SCU80[15]=1 & SCU90[31]=0 SPICS1# SCU3C[3]=1 & SCU80[15]=1 & SCU90[31]=1 GPIOB7 | ||
83 | * -----+---------+-----------+-----------------------------------------+-----------+----------------------------------------+---------- | ||
84 | * | ||
85 | * (Bits SCU3C[3] and SCU80[15] appear to only be used in the expressions for | ||
86 | * selecting the signals on pin E18) | ||
87 | * | ||
88 | * Pin T5 is a multi-signal pin with a more complex configuration: | ||
89 | * | ||
90 | * Ball | Default | P0 Signal | P0 Expression | P1 Signal | P1 Expression | Other | ||
91 | * -----+---------+-----------+------------------------------+-----------+---------------+---------- | ||
92 | * T5 GPIOL1 VPIDE SCU90[5:4]!=0 & SCU84[17]=1 NDCD1 SCU84[17]=1 GPIOL1 | ||
93 | * -----+---------+-----------+------------------------------+-----------+---------------+---------- | ||
94 | * | ||
95 | * The high priority signal configuration is best thought of in terms of its | ||
96 | * exploded form, with reference to the SCU90[5:4] bits: | ||
97 | * | ||
98 | * * SCU90[5:4]=00: disable | ||
99 | * * SCU90[5:4]=01: 18 bits (R6/G6/B6) video mode. | ||
100 | * * SCU90[5:4]=10: 24 bits (R8/G8/B8) video mode. | ||
101 | * * SCU90[5:4]=11: 30 bits (R10/G10/B10) video mode. | ||
102 | * | ||
103 | * Re-writing: | ||
104 | * | ||
105 | * -----+---------+-----------+------------------------------+-----------+---------------+---------- | ||
106 | * T5 GPIOL1 VPIDE (SCU90[5:4]=1 & SCU84[17]=1) NDCD1 SCU84[17]=1 GPIOL1 | ||
107 | * | (SCU90[5:4]=2 & SCU84[17]=1) | ||
108 | * | (SCU90[5:4]=3 & SCU84[17]=1) | ||
109 | * -----+---------+-----------+------------------------------+-----------+---------------+---------- | ||
110 | * | ||
111 | * For reference the SCU84[17] bit configure the "UART1 NDCD1 or Video VPIDE | ||
112 | * function pin", where the signal itself is determined by whether SCU94[5:4] | ||
113 | * is disabled or in one of the 18, 24 or 30bit video modes. | ||
114 | * | ||
115 | * Other video-input-related pins require an explicit state in SCU90[5:4], e.g. | ||
116 | * W1 and U5: | ||
117 | * | ||
118 | * -----+---------+-----------+------------------------------+-----------+---------------+---------- | ||
119 | * W1 GPIOL6 VPIB0 SCU90[5:4]=3 & SCU84[22]=1 TXD1 SCU84[22]=1 GPIOL6 | ||
120 | * U5 GPIOL7 VPIB1 SCU90[5:4]=3 & SCU84[23]=1 RXD1 SCU84[23]=1 GPIOL7 | ||
121 | * -----+---------+-----------+------------------------------+-----------+---------------+---------- | ||
122 | * | ||
123 | * The examples of T5 and W1 are particularly fertile, as they also demonstrate | ||
124 | * that despite operating as part of the video input bus each signal needs to | ||
125 | * be enabled individually via it's own SCU84 (in the cases of T5 and W1) | ||
126 | * register bit. This is a little crazy if the bus doesn't have optional | ||
127 | * signals, but is used to decent effect with some of the UARTs where not all | ||
128 | * signals are required. However, this isn't done consistently - UART1 is | ||
129 | * enabled on a per-pin basis, and by contrast, all signals for UART6 are | ||
130 | * enabled by a single bit. | ||
131 | * | ||
132 | * Further, the high and low priority signals listed in the table above share | ||
133 | * a configuration bit. The VPI signals should operate in concert in a single | ||
134 | * function, but the UART signals should retain the ability to be configured | ||
135 | * independently. This pushes the implementation down the path of tagging a | ||
136 | * signal's expressions with the function they participate in, rather than | ||
137 | * defining masks affecting multiple signals per function. The latter approach | ||
138 | * fails in this instance where applying the configuration for the UART pin of | ||
139 | * interest will stomp on the state of other UART signals when disabling the | ||
140 | * VPI functions on the current pin. | ||
141 | * | ||
142 | * Ball | Default | P0 Signal | P0 Expression | P1 Signal | P1 Expression | Other | ||
143 | * -----+------------+-----------+---------------------------+-----------+---------------+------------ | ||
144 | * A12 RGMII1TXCK GPIOT0 SCUA0[0]=1 RMII1TXEN Strap[6]=0 RGMII1TXCK | ||
145 | * B12 RGMII1TXCTL GPIOT1 SCUA0[1]=1 – Strap[6]=0 RGMII1TXCTL | ||
146 | * -----+------------+-----------+---------------------------+-----------+---------------+------------ | ||
147 | * | ||
148 | * A12 demonstrates that the "Other" signal isn't always GPIO - in this case | ||
149 | * GPIOT0 is a high-priority signal and RGMII1TXCK is Other. Thus, GPIO | ||
150 | * should be treated like any other signal type with full function expression | ||
151 | * requirements, and not assumed to be the default case. Separately, GPIOT0 and | ||
152 | * GPIOT1's signal descriptor bits are distinct, therefore we must iterate all | ||
153 | * pins in the function's group to disable the higher-priority signals such | ||
154 | * that the signal for the function of interest is correctly enabled. | ||
155 | * | ||
156 | * Finally, three priority levels aren't always enough; the AST2500 brings with | ||
157 | * it 18 pins of five priority levels, however the 18 pins only use three of | ||
158 | * the five priority levels. | ||
159 | * | ||
160 | * Ultimately the requirement to control pins in the examples above drive the | ||
161 | * design: | ||
162 | * | ||
163 | * * Pins provide signals according to functions activated in the mux | ||
164 | * configuration | ||
165 | * | ||
166 | * * Pins provide up to five signal types in a priority order | ||
167 | * | ||
168 | * * For priorities levels defined on a pin, each priority provides one signal | ||
169 | * | ||
170 | * * Enabling lower priority signals requires higher priority signals be | ||
171 | * disabled | ||
172 | * | ||
173 | * * A function represents a set of signals; functions are distinct if their | ||
174 | * sets of signals are not equal | ||
175 | * | ||
176 | * * Signals participate in one or more functions | ||
177 | * | ||
178 | * * A function is described by an expression of one or more signal | ||
179 | * descriptors, which compare bit values in a register | ||
180 | * | ||
181 | * * A signal expression is the smallest set of signal descriptors whose | ||
182 | * comparisons must evaluate 'true' for a signal to be enabled on a pin. | ||
183 | * | ||
184 | * * A function's signal is active on a pin if evaluating all signal | ||
185 | * descriptors in the pin's signal expression for the function yields a 'true' | ||
186 | * result | ||
187 | * | ||
188 | * * A signal at a given priority on a given pin is active if any of the | ||
189 | * functions in which the signal participates are active, and no higher | ||
190 | * priority signal on the pin is active | ||
191 | * | ||
192 | * * GPIO is configured per-pin | ||
193 | * | ||
194 | * And so: | ||
195 | * | ||
196 | * * To disable a signal, any function(s) activating the signal must be | ||
197 | * disabled | ||
198 | * | ||
199 | * * Each pin must know the signal expressions of functions in which it | ||
200 | * participates, for the purpose of enabling the Other function. This is done | ||
201 | * by deactivating all functions that activate higher priority signals on the | ||
202 | * pin. | ||
203 | * | ||
204 | * As a concrete example: | ||
205 | * | ||
206 | * * T5 provides three signals types: VPIDE, NDCD1 and GPIO | ||
207 | * | ||
208 | * * The VPIDE signal participates in 3 functions: VPI18, VPI24 and VPI30 | ||
209 | * | ||
210 | * * The NDCD1 signal participates in just its own NDCD1 function | ||
211 | * | ||
212 | * * VPIDE is high priority, NDCD1 is low priority, and GPIOL1 is the least | ||
213 | * prioritised | ||
214 | * | ||
215 | * * The prerequisit for activating the NDCD1 signal is that the VPI18, VPI24 | ||
216 | * and VPI30 functions all be disabled | ||
217 | * | ||
218 | * * Similarly, all of VPI18, VPI24, VPI30 and NDCD1 functions must be disabled | ||
219 | * to provide GPIOL6 | ||
220 | * | ||
221 | * Considerations | ||
222 | * -------------- | ||
223 | * | ||
224 | * If pinctrl allows us to allocate a pin we can configure a function without | ||
225 | * concern for the function of already allocated pins, if pin groups are | ||
226 | * created with respect to the SoC functions in which they participate. This is | ||
227 | * intuitive, but it did not feel obvious from the bit/pin relationships. | ||
228 | * | ||
229 | * Conversely, failing to allocate all pins in a group indicates some bits (as | ||
230 | * well as pins) required for the group's configuration will already be in use, | ||
231 | * likely in a way that's inconsistent with the requirements of the failed | ||
232 | * group. | ||
233 | */ | ||
234 | |||
235 | /* | ||
236 | * The "Multi-function Pins Mapping and Control" table in the SoC datasheet | ||
237 | * references registers by the device/offset mnemonic. The register macros | ||
238 | * below are named the same way to ease transcription and verification (as | ||
239 | * opposed to naming them e.g. PINMUX_CTRL_[0-9]). Further, signal expressions | ||
240 | * reference registers beyond those dedicated to pinmux, such as the system | ||
241 | * reset control and MAC clock configuration registers. The AST2500 goes a step | ||
242 | * further and references registers in the graphics IP block, but that isn't | ||
243 | * handled yet. | ||
244 | */ | ||
245 | #define SCU2C 0x2C /* Misc. Control Register */ | ||
246 | #define SCU3C 0x3C /* System Reset Control/Status Register */ | ||
247 | #define SCU48 0x48 /* MAC Interface Clock Delay Setting */ | ||
248 | #define HW_STRAP1 0x70 /* AST2400 strapping is 33 bits, is split */ | ||
249 | #define SCU80 0x80 /* Multi-function Pin Control #1 */ | ||
250 | #define SCU84 0x84 /* Multi-function Pin Control #2 */ | ||
251 | #define SCU88 0x88 /* Multi-function Pin Control #3 */ | ||
252 | #define SCU8C 0x8C /* Multi-function Pin Control #4 */ | ||
253 | #define SCU90 0x90 /* Multi-function Pin Control #5 */ | ||
254 | #define SCU94 0x94 /* Multi-function Pin Control #6 */ | ||
255 | #define SCUA0 0xA0 /* Multi-function Pin Control #7 */ | ||
256 | #define SCUA4 0xA4 /* Multi-function Pin Control #8 */ | ||
257 | #define SCUA8 0xA8 /* Multi-function Pin Control #9 */ | ||
258 | #define HW_STRAP2 0xD0 /* Strapping */ | ||
259 | |||
260 | /** | ||
261 | * A signal descriptor, which describes the register, bits and the | ||
262 | * enable/disable values that should be compared or written. | ||
263 | * | ||
264 | * @reg: The register offset from base in bytes | ||
265 | * @mask: The mask to apply to the register. The lowest set bit of the mask is | ||
266 | * used to derive the shift value. | ||
267 | * @enable: The value that enables the function. Value should be in the LSBs, | ||
268 | * not at the position of the mask. | ||
269 | * @disable: The value that disables the function. Value should be in the | ||
270 | * LSBs, not at the position of the mask. | ||
271 | */ | ||
272 | struct aspeed_sig_desc { | ||
273 | unsigned int reg; | ||
274 | u32 mask; | ||
275 | u32 enable; | ||
276 | u32 disable; | ||
277 | }; | ||
278 | |||
279 | /** | ||
280 | * Describes a signal expression. The expression is evaluated by ANDing the | ||
281 | * evaluation of the descriptors. | ||
282 | * | ||
283 | * @signal: The signal name for the priority level on the pin. If the signal | ||
284 | * type is GPIO, then the signal name must begin with the string | ||
285 | * "GPIO", e.g. GPIOA0, GPIOT4 etc. | ||
286 | * @function: The name of the function the signal participates in for the | ||
287 | * associated expression | ||
288 | * @ndescs: The number of signal descriptors in the expression | ||
289 | * @descs: Pointer to an array of signal descriptors that comprise the | ||
290 | * function expression | ||
291 | */ | ||
292 | struct aspeed_sig_expr { | ||
293 | const char *signal; | ||
294 | const char *function; | ||
295 | int ndescs; | ||
296 | const struct aspeed_sig_desc *descs; | ||
297 | }; | ||
298 | |||
299 | /** | ||
300 | * A struct capturing the list of expressions enabling signals at each priority | ||
301 | * for a given pin. The signal configuration for a priority level is evaluated | ||
302 | * by ORing the evaluation of the signal expressions in the respective | ||
303 | * priority's list. | ||
304 | * | ||
305 | * @name: A name for the pin | ||
306 | * @prios: A pointer to an array of expression list pointers | ||
307 | * | ||
308 | */ | ||
309 | struct aspeed_pin_desc { | ||
310 | const char *name; | ||
311 | const struct aspeed_sig_expr ***prios; | ||
312 | }; | ||
313 | |||
314 | /* Macro hell */ | ||
315 | |||
316 | /** | ||
317 | * Short-hand macro for describing a configuration enabled by the state of one | ||
318 | * bit. The disable value is derived. | ||
319 | * | ||
320 | * @reg: The signal's associated register, offset from base | ||
321 | * @idx: The signal's bit index in the register | ||
322 | * @val: The value (0 or 1) that enables the function | ||
323 | */ | ||
324 | #define SIG_DESC_BIT(reg, idx, val) \ | ||
325 | { reg, BIT_MASK(idx), val, (((val) + 1) & 1) } | ||
326 | |||
327 | /** | ||
328 | * A further short-hand macro describing a configuration enabled with a set bit. | ||
329 | * | ||
330 | * @reg: The configuration's associated register, offset from base | ||
331 | * @idx: The configuration's bit index in the register | ||
332 | */ | ||
333 | #define SIG_DESC_SET(reg, idx) SIG_DESC_BIT(reg, idx, 1) | ||
334 | |||
335 | #define SIG_DESC_LIST_SYM(sig, func) sig_descs_ ## sig ## _ ## func | ||
336 | #define SIG_DESC_LIST_DECL(sig, func, ...) \ | ||
337 | static const struct aspeed_sig_desc SIG_DESC_LIST_SYM(sig, func)[] = \ | ||
338 | { __VA_ARGS__ } | ||
339 | |||
340 | #define SIG_EXPR_SYM(sig, func) sig_expr_ ## sig ## _ ## func | ||
341 | #define SIG_EXPR_DECL_(sig, func) \ | ||
342 | static const struct aspeed_sig_expr SIG_EXPR_SYM(sig, func) = \ | ||
343 | { \ | ||
344 | .signal = #sig, \ | ||
345 | .function = #func, \ | ||
346 | .ndescs = ARRAY_SIZE(SIG_DESC_LIST_SYM(sig, func)), \ | ||
347 | .descs = &(SIG_DESC_LIST_SYM(sig, func))[0], \ | ||
348 | } | ||
349 | |||
350 | /** | ||
351 | * Declare a signal expression. | ||
352 | * | ||
353 | * @sig: A macro symbol name for the signal (is subjected to stringification | ||
354 | * and token pasting) | ||
355 | * @func: The function in which the signal is participating | ||
356 | * @...: Signal descriptors that define the signal expression | ||
357 | * | ||
358 | * For example, the following declares the ROMD8 signal for the ROM16 function: | ||
359 | * | ||
360 | * SIG_EXPR_DECL(ROMD8, ROM16, SIG_DESC_SET(SCU90, 6)); | ||
361 | * | ||
362 | * And with multiple signal descriptors: | ||
363 | * | ||
364 | * SIG_EXPR_DECL(ROMD8, ROM16S, SIG_DESC_SET(HW_STRAP1, 4), | ||
365 | * { HW_STRAP1, GENMASK(1, 0), 0, 0 }); | ||
366 | */ | ||
367 | #define SIG_EXPR_DECL(sig, func, ...) \ | ||
368 | SIG_DESC_LIST_DECL(sig, func, __VA_ARGS__); \ | ||
369 | SIG_EXPR_DECL_(sig, func) | ||
370 | |||
371 | /** | ||
372 | * Declare a pointer to a signal expression | ||
373 | * | ||
374 | * @sig: The macro symbol name for the signal (subjected to token pasting) | ||
375 | * @func: The macro symbol name for the function (subjected to token pasting) | ||
376 | */ | ||
377 | #define SIG_EXPR_PTR(sig, func) (&SIG_EXPR_SYM(sig, func)) | ||
378 | |||
379 | #define SIG_EXPR_LIST_SYM(sig) sig_exprs_ ## sig | ||
380 | |||
381 | /** | ||
382 | * Declare a signal expression list for reference in a struct aspeed_pin_prio. | ||
383 | * | ||
384 | * @sig: A macro symbol name for the signal (is subjected to token pasting) | ||
385 | * @...: Signal expression structure pointers (use SIG_EXPR_PTR()) | ||
386 | * | ||
387 | * For example, the 16-bit ROM bus can be enabled by one of two possible signal | ||
388 | * expressions: | ||
389 | * | ||
390 | * SIG_EXPR_DECL(ROMD8, ROM16, SIG_DESC_SET(SCU90, 6)); | ||
391 | * SIG_EXPR_DECL(ROMD8, ROM16S, SIG_DESC_SET(HW_STRAP1, 4), | ||
392 | * { HW_STRAP1, GENMASK(1, 0), 0, 0 }); | ||
393 | * SIG_EXPR_LIST_DECL(ROMD8, SIG_EXPR_PTR(ROMD8, ROM16), | ||
394 | * SIG_EXPR_PTR(ROMD8, ROM16S)); | ||
395 | */ | ||
396 | #define SIG_EXPR_LIST_DECL(sig, ...) \ | ||
397 | static const struct aspeed_sig_expr *SIG_EXPR_LIST_SYM(sig)[] = \ | ||
398 | { __VA_ARGS__, NULL } | ||
399 | |||
400 | /** | ||
401 | * A short-hand macro for declaring a function expression and an expression | ||
402 | * list with a single function. | ||
403 | * | ||
404 | * @func: A macro symbol name for the function (is subjected to token pasting) | ||
405 | * @...: Function descriptors that define the function expression | ||
406 | * | ||
407 | * For example, signal NCTS6 participates in its own function with one group: | ||
408 | * | ||
409 | * SIG_EXPR_LIST_DECL_SINGLE(NCTS6, NCTS6, SIG_DESC_SET(SCU90, 7)); | ||
410 | */ | ||
411 | #define SIG_EXPR_LIST_DECL_SINGLE(sig, func, ...) \ | ||
412 | SIG_DESC_LIST_DECL(sig, func, __VA_ARGS__); \ | ||
413 | SIG_EXPR_DECL_(sig, func); \ | ||
414 | SIG_EXPR_LIST_DECL(sig, SIG_EXPR_PTR(sig, func)) | ||
415 | |||
416 | #define SIG_EXPR_LIST_DECL_DUAL(sig, f0, f1) \ | ||
417 | SIG_EXPR_LIST_DECL(sig, SIG_EXPR_PTR(sig, f0), SIG_EXPR_PTR(sig, f1)) | ||
418 | |||
419 | #define SIG_EXPR_LIST_PTR(sig) (&SIG_EXPR_LIST_SYM(sig)[0]) | ||
420 | |||
421 | #define PIN_EXPRS_SYM(pin) pin_exprs_ ## pin | ||
422 | #define PIN_EXPRS_PTR(pin) (&PIN_EXPRS_SYM(pin)[0]) | ||
423 | #define PIN_SYM(pin) pin_ ## pin | ||
424 | |||
425 | #define MS_PIN_DECL_(pin, ...) \ | ||
426 | static const struct aspeed_sig_expr **PIN_EXPRS_SYM(pin)[] = \ | ||
427 | { __VA_ARGS__, NULL }; \ | ||
428 | static const struct aspeed_pin_desc PIN_SYM(pin) = \ | ||
429 | { #pin, PIN_EXPRS_PTR(pin) } | ||
430 | |||
431 | /** | ||
432 | * Declare a multi-signal pin | ||
433 | * | ||
434 | * @pin: The pin number | ||
435 | * @other: Macro name for "other" functionality (subjected to stringification) | ||
436 | * @high: Macro name for the highest priority signal functions | ||
437 | * @low: Macro name for the low signal functions | ||
438 | * | ||
439 | * For example: | ||
440 | * | ||
441 | * #define A8 56 | ||
442 | * SIG_EXPR_DECL(ROMD8, ROM16, SIG_DESC_SET(SCU90, 6)); | ||
443 | * SIG_EXPR_DECL(ROMD8, ROM16S, SIG_DESC_SET(HW_STRAP1, 4), | ||
444 | * { HW_STRAP1, GENMASK(1, 0), 0, 0 }); | ||
445 | * SIG_EXPR_LIST_DECL(ROMD8, SIG_EXPR_PTR(ROMD8, ROM16), | ||
446 | * SIG_EXPR_PTR(ROMD8, ROM16S)); | ||
447 | * SIG_EXPR_LIST_DECL_SINGLE(NCTS6, NCTS6, SIG_DESC_SET(SCU90, 7)); | ||
448 | * MS_PIN_DECL(A8, GPIOH0, ROMD8, NCTS6); | ||
449 | */ | ||
450 | #define MS_PIN_DECL(pin, other, high, low) \ | ||
451 | SIG_EXPR_LIST_DECL_SINGLE(other, other); \ | ||
452 | MS_PIN_DECL_(pin, \ | ||
453 | SIG_EXPR_LIST_PTR(high), \ | ||
454 | SIG_EXPR_LIST_PTR(low), \ | ||
455 | SIG_EXPR_LIST_PTR(other)) | ||
456 | |||
457 | #define PIN_GROUP_SYM(func) pins_ ## func | ||
458 | #define FUNC_GROUP_SYM(func) groups_ ## func | ||
459 | #define FUNC_GROUP_DECL(func, ...) \ | ||
460 | static const int PIN_GROUP_SYM(func)[] = { __VA_ARGS__ }; \ | ||
461 | static const char *FUNC_GROUP_SYM(func)[] = { #func } | ||
462 | |||
463 | /** | ||
464 | * Declare a single signal pin | ||
465 | * | ||
466 | * @pin: The pin number | ||
467 | * @other: Macro name for "other" functionality (subjected to stringification) | ||
468 | * @sig: Macro name for the signal (subjected to stringification) | ||
469 | * | ||
470 | * For example: | ||
471 | * | ||
472 | * #define E3 80 | ||
473 | * SIG_EXPR_LIST_DECL_SINGLE(SCL5, I2C5, I2C5_DESC); | ||
474 | * SS_PIN_DECL(E3, GPIOK0, SCL5); | ||
475 | */ | ||
476 | #define SS_PIN_DECL(pin, other, sig) \ | ||
477 | SIG_EXPR_LIST_DECL_SINGLE(other, other); \ | ||
478 | MS_PIN_DECL_(pin, SIG_EXPR_LIST_PTR(sig), SIG_EXPR_LIST_PTR(other)) | ||
479 | |||
480 | /** | ||
481 | * Single signal, single function pin declaration | ||
482 | * | ||
483 | * @pin: The pin number | ||
484 | * @other: Macro name for "other" functionality (subjected to stringification) | ||
485 | * @sig: Macro name for the signal (subjected to stringification) | ||
486 | * @...: Signal descriptors that define the function expression | ||
487 | * | ||
488 | * For example: | ||
489 | * | ||
490 | * SSSF_PIN_DECL(A4, GPIOA2, TIMER3, SIG_DESC_SET(SCU80, 2)); | ||
491 | */ | ||
492 | #define SSSF_PIN_DECL(pin, other, sig, ...) \ | ||
493 | SIG_EXPR_LIST_DECL_SINGLE(sig, sig, __VA_ARGS__); \ | ||
494 | SIG_EXPR_LIST_DECL_SINGLE(other, other); \ | ||
495 | MS_PIN_DECL_(pin, SIG_EXPR_LIST_PTR(sig), SIG_EXPR_LIST_PTR(other)); \ | ||
496 | FUNC_GROUP_DECL(sig, pin) | ||
497 | |||
498 | #define GPIO_PIN_DECL(pin, gpio) \ | ||
499 | SIG_EXPR_LIST_DECL_SINGLE(gpio, gpio); \ | ||
500 | MS_PIN_DECL_(pin, SIG_EXPR_LIST_PTR(gpio)) | ||
501 | |||
502 | struct aspeed_pinctrl_data { | ||
503 | struct regmap *map; | ||
504 | |||
505 | const struct pinctrl_pin_desc *pins; | ||
506 | const unsigned int npins; | ||
507 | |||
508 | const struct aspeed_pin_group *groups; | ||
509 | const unsigned int ngroups; | ||
510 | |||
511 | const struct aspeed_pin_function *functions; | ||
512 | const unsigned int nfunctions; | ||
513 | }; | ||
514 | |||
515 | #define ASPEED_PINCTRL_PIN(name_) \ | ||
516 | [name_] = { \ | ||
517 | .number = name_, \ | ||
518 | .name = #name_, \ | ||
519 | .drv_data = (void *) &(PIN_SYM(name_)) \ | ||
520 | } | ||
521 | |||
522 | struct aspeed_pin_group { | ||
523 | const char *name; | ||
524 | const unsigned int *pins; | ||
525 | const unsigned int npins; | ||
526 | }; | ||
527 | |||
528 | #define ASPEED_PINCTRL_GROUP(name_) { \ | ||
529 | .name = #name_, \ | ||
530 | .pins = &(PIN_GROUP_SYM(name_))[0], \ | ||
531 | .npins = ARRAY_SIZE(PIN_GROUP_SYM(name_)), \ | ||
532 | } | ||
533 | |||
534 | struct aspeed_pin_function { | ||
535 | const char *name; | ||
536 | const char *const *groups; | ||
537 | unsigned int ngroups; | ||
538 | }; | ||
539 | |||
540 | #define ASPEED_PINCTRL_FUNC(name_, ...) { \ | ||
541 | .name = #name_, \ | ||
542 | .groups = &FUNC_GROUP_SYM(name_)[0], \ | ||
543 | .ngroups = ARRAY_SIZE(FUNC_GROUP_SYM(name_)), \ | ||
544 | } | ||
545 | |||
546 | int aspeed_pinctrl_get_groups_count(struct pinctrl_dev *pctldev); | ||
547 | const char *aspeed_pinctrl_get_group_name(struct pinctrl_dev *pctldev, | ||
548 | unsigned int group); | ||
549 | int aspeed_pinctrl_get_group_pins(struct pinctrl_dev *pctldev, | ||
550 | unsigned int group, const unsigned int **pins, | ||
551 | unsigned int *npins); | ||
552 | void aspeed_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev, | ||
553 | struct seq_file *s, unsigned int offset); | ||
554 | int aspeed_pinmux_get_fn_count(struct pinctrl_dev *pctldev); | ||
555 | const char *aspeed_pinmux_get_fn_name(struct pinctrl_dev *pctldev, | ||
556 | unsigned int function); | ||
557 | int aspeed_pinmux_get_fn_groups(struct pinctrl_dev *pctldev, | ||
558 | unsigned int function, const char * const **groups, | ||
559 | unsigned int * const num_groups); | ||
560 | int aspeed_pinmux_set_mux(struct pinctrl_dev *pctldev, unsigned int function, | ||
561 | unsigned int group); | ||
562 | int aspeed_gpio_request_enable(struct pinctrl_dev *pctldev, | ||
563 | struct pinctrl_gpio_range *range, | ||
564 | unsigned int offset); | ||
565 | int aspeed_pinctrl_probe(struct platform_device *pdev, | ||
566 | struct pinctrl_desc *pdesc, | ||
567 | struct aspeed_pinctrl_data *pdata); | ||
568 | |||
569 | #endif /* PINCTRL_ASPEED */ | ||