pinctrl: sunxi: Add NAND pinmuxes
[platform/kernel/u-boot.git] / drivers / pinctrl / sunxi / pinctrl-sunxi.c
1 // SPDX-License-Identifier: GPL-2.0
2
3 #include <clk.h>
4 #include <dm.h>
5 #include <dm/device-internal.h>
6 #include <dm/lists.h>
7 #include <dm/pinctrl.h>
8 #include <errno.h>
9 #include <malloc.h>
10
11 #include <asm/gpio.h>
12
13 extern U_BOOT_DRIVER(gpio_sunxi);
14
15 /*
16  * This structure implements a simplified view of the possible pinmux settings:
17  * Each mux value is assumed to be the same for a given function, across the
18  * pins in each group (almost universally true, with same rare exceptions not
19  * relevant to U-Boot), but also across different ports (not true in many
20  * cases). We ignore the first problem, and work around the latter by just
21  * supporting one particular port for a each function. This works fine for all
22  * board configurations so far. If this would need to be revisited, we could
23  * add a "u8 port;" below and match that, with 0 encoding the "don't care" case.
24  */
25 struct sunxi_pinctrl_function {
26         const char      name[sizeof("gpio_out")];
27         u8              mux;
28 };
29
30 struct sunxi_pinctrl_desc {
31         const struct sunxi_pinctrl_function     *functions;
32         u8                                      num_functions;
33         u8                                      first_bank;
34         u8                                      num_banks;
35 };
36
37 struct sunxi_pinctrl_plat {
38         struct sunxi_gpio __iomem *base;
39 };
40
41 static int sunxi_pinctrl_get_pins_count(struct udevice *dev)
42 {
43         const struct sunxi_pinctrl_desc *desc = dev_get_priv(dev);
44
45         return desc->num_banks * SUNXI_GPIOS_PER_BANK;
46 }
47
48 static const char *sunxi_pinctrl_get_pin_name(struct udevice *dev,
49                                               uint pin_selector)
50 {
51         const struct sunxi_pinctrl_desc *desc = dev_get_priv(dev);
52         static char pin_name[sizeof("PN31")];
53
54         snprintf(pin_name, sizeof(pin_name), "P%c%d",
55                  pin_selector / SUNXI_GPIOS_PER_BANK + desc->first_bank + 'A',
56                  pin_selector % SUNXI_GPIOS_PER_BANK);
57
58         return pin_name;
59 }
60
61 static int sunxi_pinctrl_get_functions_count(struct udevice *dev)
62 {
63         const struct sunxi_pinctrl_desc *desc = dev_get_priv(dev);
64
65         return desc->num_functions;
66 }
67
68 static const char *sunxi_pinctrl_get_function_name(struct udevice *dev,
69                                                    uint func_selector)
70 {
71         const struct sunxi_pinctrl_desc *desc = dev_get_priv(dev);
72
73         return desc->functions[func_selector].name;
74 }
75
76 static int sunxi_pinctrl_pinmux_set(struct udevice *dev, uint pin_selector,
77                                     uint func_selector)
78 {
79         const struct sunxi_pinctrl_desc *desc = dev_get_priv(dev);
80         struct sunxi_pinctrl_plat *plat = dev_get_plat(dev);
81         int bank = pin_selector / SUNXI_GPIOS_PER_BANK;
82         int pin  = pin_selector % SUNXI_GPIOS_PER_BANK;
83
84         debug("set mux: %-4s => %s (%d)\n",
85               sunxi_pinctrl_get_pin_name(dev, pin_selector),
86               sunxi_pinctrl_get_function_name(dev, func_selector),
87               desc->functions[func_selector].mux);
88
89         sunxi_gpio_set_cfgbank(plat->base + bank, pin,
90                                desc->functions[func_selector].mux);
91
92         return 0;
93 }
94
95 static const struct pinconf_param sunxi_pinctrl_pinconf_params[] = {
96         { "bias-disable",       PIN_CONFIG_BIAS_DISABLE,         0 },
97         { "bias-pull-down",     PIN_CONFIG_BIAS_PULL_DOWN,       2 },
98         { "bias-pull-up",       PIN_CONFIG_BIAS_PULL_UP,         1 },
99         { "drive-strength",     PIN_CONFIG_DRIVE_STRENGTH,      10 },
100 };
101
102 static int sunxi_pinctrl_pinconf_set_pull(struct sunxi_pinctrl_plat *plat,
103                                           uint bank, uint pin, uint bias)
104 {
105         struct sunxi_gpio *regs = &plat->base[bank];
106
107         sunxi_gpio_set_pull_bank(regs, pin, bias);
108
109         return 0;
110 }
111
112 static int sunxi_pinctrl_pinconf_set_drive(struct sunxi_pinctrl_plat *plat,
113                                            uint bank, uint pin, uint drive)
114 {
115         struct sunxi_gpio *regs = &plat->base[bank];
116
117         if (drive < 10 || drive > 40)
118                 return -EINVAL;
119
120         /* Convert mA to the register value, rounding down. */
121         sunxi_gpio_set_drv_bank(regs, pin, drive / 10 - 1);
122
123         return 0;
124 }
125
126 static int sunxi_pinctrl_pinconf_set(struct udevice *dev, uint pin_selector,
127                                      uint param, uint val)
128 {
129         struct sunxi_pinctrl_plat *plat = dev_get_plat(dev);
130         int bank = pin_selector / SUNXI_GPIOS_PER_BANK;
131         int pin  = pin_selector % SUNXI_GPIOS_PER_BANK;
132
133         switch (param) {
134         case PIN_CONFIG_BIAS_DISABLE:
135         case PIN_CONFIG_BIAS_PULL_DOWN:
136         case PIN_CONFIG_BIAS_PULL_UP:
137                 return sunxi_pinctrl_pinconf_set_pull(plat, bank, pin, val);
138         case PIN_CONFIG_DRIVE_STRENGTH:
139                 return sunxi_pinctrl_pinconf_set_drive(plat, bank, pin, val);
140         }
141
142         return -EINVAL;
143 }
144
145 static int sunxi_pinctrl_get_pin_muxing(struct udevice *dev, uint pin_selector,
146                                         char *buf, int size)
147 {
148         struct sunxi_pinctrl_plat *plat = dev_get_plat(dev);
149         int bank = pin_selector / SUNXI_GPIOS_PER_BANK;
150         int pin  = pin_selector % SUNXI_GPIOS_PER_BANK;
151         int mux  = sunxi_gpio_get_cfgbank(plat->base + bank, pin);
152
153         switch (mux) {
154         case SUNXI_GPIO_INPUT:
155                 strlcpy(buf, "gpio input", size);
156                 break;
157         case SUNXI_GPIO_OUTPUT:
158                 strlcpy(buf, "gpio output", size);
159                 break;
160         case SUNXI_GPIO_DISABLE:
161                 strlcpy(buf, "disabled", size);
162                 break;
163         default:
164                 snprintf(buf, size, "function %d", mux);
165                 break;
166         }
167
168         return 0;
169 }
170
171 static const struct pinctrl_ops sunxi_pinctrl_ops = {
172         .get_pins_count         = sunxi_pinctrl_get_pins_count,
173         .get_pin_name           = sunxi_pinctrl_get_pin_name,
174         .get_functions_count    = sunxi_pinctrl_get_functions_count,
175         .get_function_name      = sunxi_pinctrl_get_function_name,
176         .pinmux_set             = sunxi_pinctrl_pinmux_set,
177         .pinconf_num_params     = ARRAY_SIZE(sunxi_pinctrl_pinconf_params),
178         .pinconf_params         = sunxi_pinctrl_pinconf_params,
179         .pinconf_set            = sunxi_pinctrl_pinconf_set,
180         .set_state              = pinctrl_generic_set_state,
181         .get_pin_muxing         = sunxi_pinctrl_get_pin_muxing,
182 };
183
184 static int sunxi_pinctrl_bind(struct udevice *dev)
185 {
186         struct sunxi_pinctrl_plat *plat = dev_get_plat(dev);
187         struct sunxi_pinctrl_desc *desc;
188         struct sunxi_gpio_plat *gpio_plat;
189         struct udevice *gpio_dev;
190         int i, ret;
191
192         desc = (void *)dev_get_driver_data(dev);
193         if (!desc)
194                 return -EINVAL;
195         dev_set_priv(dev, desc);
196
197         plat->base = dev_read_addr_ptr(dev);
198
199         ret = device_bind_driver_to_node(dev, "gpio_sunxi", dev->name,
200                                          dev_ofnode(dev), &gpio_dev);
201         if (ret)
202                 return ret;
203
204         for (i = 0; i < desc->num_banks; ++i) {
205                 gpio_plat = malloc(sizeof(*gpio_plat));
206                 if (!gpio_plat)
207                         return -ENOMEM;
208
209                 gpio_plat->regs = plat->base + i;
210                 gpio_plat->bank_name[0] = 'P';
211                 gpio_plat->bank_name[1] = 'A' + desc->first_bank + i;
212                 gpio_plat->bank_name[2] = '\0';
213
214                 ret = device_bind(gpio_dev, DM_DRIVER_REF(gpio_sunxi),
215                                   gpio_plat->bank_name, gpio_plat,
216                                   ofnode_null(), NULL);
217                 if (ret)
218                         return ret;
219         }
220
221         return 0;
222 }
223
224 static int sunxi_pinctrl_probe(struct udevice *dev)
225 {
226         struct clk *apb_clk;
227
228         apb_clk = devm_clk_get(dev, "apb");
229         if (!IS_ERR(apb_clk))
230                 clk_enable(apb_clk);
231
232         return 0;
233 }
234
235 static const struct sunxi_pinctrl_function suniv_f1c100s_pinctrl_functions[] = {
236         { "gpio_in",    0 },
237         { "gpio_out",   1 },
238         { "i2c0",       3 },    /* PE11-PE12 */
239         { "i2c1",       3 },    /* PD5-PD6 */
240         { "mmc0",       2 },    /* PF0-PF5 */
241         { "mmc1",       3 },    /* PC0-PC2 */
242         { "spi0",       2 },    /* PC0-PC3 */
243 #if IS_ENABLED(CONFIG_UART0_PORT_F)
244         { "uart0",      3 },    /* PF2-PF4 */
245 #else
246         { "uart0",      5 },    /* PE0-PE1 */
247 #endif
248         { "uart1",      5 },    /* PA0-PA3 */
249 };
250
251 static const struct sunxi_pinctrl_desc __maybe_unused suniv_f1c100s_pinctrl_desc = {
252         .functions      = suniv_f1c100s_pinctrl_functions,
253         .num_functions  = ARRAY_SIZE(suniv_f1c100s_pinctrl_functions),
254         .first_bank     = SUNXI_GPIO_A,
255         .num_banks      = 6,
256 };
257
258 static const struct sunxi_pinctrl_function sun4i_a10_pinctrl_functions[] = {
259         { "emac",       2 },    /* PA0-PA17 */
260         { "gpio_in",    0 },
261         { "gpio_out",   1 },
262         { "i2c0",       2 },    /* PB0-PB1 */
263         { "i2c1",       2 },    /* PB18-PB19 */
264         { "mmc0",       2 },    /* PF0-PF5 */
265 #if IS_ENABLED(CONFIG_MMC1_PINS_PH)
266         { "mmc1",       5 },    /* PH22-PH27 */
267 #else
268         { "mmc1",       4 },    /* PG0-PG5 */
269 #endif
270         { "mmc2",       3 },    /* PC6-PC15 */
271         { "mmc3",       2 },    /* PI4-PI9 */
272         { "nand0",      2 },    /* PC0-PC24 */
273         { "spi0",       3 },    /* PC0-PC2, PC23 */
274 #if IS_ENABLED(CONFIG_UART0_PORT_F)
275         { "uart0",      4 },    /* PF2-PF4 */
276 #else
277         { "uart0",      2 },    /* PB22-PB23 */
278 #endif
279 };
280
281 static const struct sunxi_pinctrl_desc __maybe_unused sun4i_a10_pinctrl_desc = {
282         .functions      = sun4i_a10_pinctrl_functions,
283         .num_functions  = ARRAY_SIZE(sun4i_a10_pinctrl_functions),
284         .first_bank     = SUNXI_GPIO_A,
285         .num_banks      = 9,
286 };
287
288 static const struct sunxi_pinctrl_function sun5i_a13_pinctrl_functions[] = {
289         { "emac",       2 },    /* PA0-PA17 */
290         { "gpio_in",    0 },
291         { "gpio_out",   1 },
292         { "i2c0",       2 },    /* PB0-PB1 */
293         { "i2c1",       2 },    /* PB15-PB16 */
294         { "mmc0",       2 },    /* PF0-PF5 */
295         { "mmc1",       2 },    /* PG3-PG8 */
296         { "mmc2",       3 },    /* PC6-PC15 */
297         { "nand0",      2 },    /* PC0-PC19 */
298         { "spi0",       3 },    /* PC0-PC3 */
299 #if IS_ENABLED(CONFIG_UART0_PORT_F)
300         { "uart0",      4 },    /* PF2-PF4 */
301 #else
302         { "uart0",      2 },    /* PB19-PB20 */
303 #endif
304         { "uart1",      4 },    /* PG3-PG4 */
305 };
306
307 static const struct sunxi_pinctrl_desc __maybe_unused sun5i_a13_pinctrl_desc = {
308         .functions      = sun5i_a13_pinctrl_functions,
309         .num_functions  = ARRAY_SIZE(sun5i_a13_pinctrl_functions),
310         .first_bank     = SUNXI_GPIO_A,
311         .num_banks      = 7,
312 };
313
314 static const struct sunxi_pinctrl_function sun6i_a31_pinctrl_functions[] = {
315         { "gmac",       2 },    /* PA0-PA27 */
316         { "gpio_in",    0 },
317         { "gpio_out",   1 },
318         { "i2c0",       2 },    /* PH14-PH15 */
319         { "i2c1",       2 },    /* PH16-PH17 */
320         { "mmc0",       2 },    /* PF0-PF5 */
321         { "mmc1",       2 },    /* PG0-PG5 */
322         { "mmc2",       3 },    /* PC6-PC15, PC24 */
323         { "mmc3",       4 },    /* PC6-PC15, PC24 */
324         { "nand0",      2 },    /* PC0-PC26 */
325         { "spi0",       3 },    /* PC0-PC2, PC27 */
326 #if IS_ENABLED(CONFIG_UART0_PORT_F)
327         { "uart0",      3 },    /* PF2-PF4 */
328 #else
329         { "uart0",      2 },    /* PH20-PH21 */
330 #endif
331 };
332
333 static const struct sunxi_pinctrl_desc __maybe_unused sun6i_a31_pinctrl_desc = {
334         .functions      = sun6i_a31_pinctrl_functions,
335         .num_functions  = ARRAY_SIZE(sun6i_a31_pinctrl_functions),
336         .first_bank     = SUNXI_GPIO_A,
337         .num_banks      = 8,
338 };
339
340 static const struct sunxi_pinctrl_function sun6i_a31_r_pinctrl_functions[] = {
341         { "gpio_in",    0 },
342         { "gpio_out",   1 },
343         { "s_i2c",      2 },    /* PL0-PL1 */
344         { "s_p2wi",     3 },    /* PL0-PL1 */
345         { "s_uart",     2 },    /* PL2-PL3 */
346 };
347
348 static const struct sunxi_pinctrl_desc __maybe_unused sun6i_a31_r_pinctrl_desc = {
349         .functions      = sun6i_a31_r_pinctrl_functions,
350         .num_functions  = ARRAY_SIZE(sun6i_a31_r_pinctrl_functions),
351         .first_bank     = SUNXI_GPIO_L,
352         .num_banks      = 2,
353 };
354
355 static const struct sunxi_pinctrl_function sun7i_a20_pinctrl_functions[] = {
356         { "emac",       2 },    /* PA0-PA17 */
357         { "gmac",       5 },    /* PA0-PA17 */
358         { "gpio_in",    0 },
359         { "gpio_out",   1 },
360         { "i2c0",       2 },    /* PB0-PB1 */
361         { "i2c1",       2 },    /* PB18-PB19 */
362         { "mmc0",       2 },    /* PF0-PF5 */
363 #if IS_ENABLED(CONFIG_MMC1_PINS_PH)
364         { "mmc1",       5 },    /* PH22-PH27 */
365 #else
366         { "mmc1",       4 },    /* PG0-PG5 */
367 #endif
368         { "mmc2",       3 },    /* PC5-PC15, PC24 */
369         { "nand0",      2 },    /* PC0-PC24 */
370         { "spi0",       3 },    /* PC0-PC2, PC23 */
371 #if IS_ENABLED(CONFIG_UART0_PORT_F)
372         { "uart0",      4 },    /* PF2-PF4 */
373 #else
374         { "uart0",      2 },    /* PB22-PB23 */
375 #endif
376 };
377
378 static const struct sunxi_pinctrl_desc __maybe_unused sun7i_a20_pinctrl_desc = {
379         .functions      = sun7i_a20_pinctrl_functions,
380         .num_functions  = ARRAY_SIZE(sun7i_a20_pinctrl_functions),
381         .first_bank     = SUNXI_GPIO_A,
382         .num_banks      = 9,
383 };
384
385 static const struct sunxi_pinctrl_function sun8i_a23_pinctrl_functions[] = {
386         { "gpio_in",    0 },
387         { "gpio_out",   1 },
388         { "i2c0",       2 },    /* PH2-PH3 */
389         { "i2c1",       2 },    /* PH4-PH5 */
390         { "mmc0",       2 },    /* PF0-PF5 */
391         { "mmc1",       2 },    /* PG0-PG5 */
392         { "mmc2",       3 },    /* PC5-PC16 */
393         { "nand0",      2 },    /* PC0-PC16 */
394         { "spi0",       3 },    /* PC0-PC3 */
395 #if IS_ENABLED(CONFIG_UART0_PORT_F)
396         { "uart0",      3 },    /* PF2-PF4 */
397 #endif
398         { "uart1",      2 },    /* PG6-PG7 */
399         { "uart2",      2 },    /* PB0-PB1 */
400 };
401
402 static const struct sunxi_pinctrl_desc __maybe_unused sun8i_a23_pinctrl_desc = {
403         .functions      = sun8i_a23_pinctrl_functions,
404         .num_functions  = ARRAY_SIZE(sun8i_a23_pinctrl_functions),
405         .first_bank     = SUNXI_GPIO_A,
406         .num_banks      = 8,
407 };
408
409 static const struct sunxi_pinctrl_function sun8i_a23_r_pinctrl_functions[] = {
410         { "gpio_in",    0 },
411         { "gpio_out",   1 },
412         { "s_i2c",      3 },    /* PL0-PL1 */
413         { "s_rsb",      2 },    /* PL0-PL1 */
414         { "s_uart",     2 },    /* PL2-PL3 */
415 };
416
417 static const struct sunxi_pinctrl_desc __maybe_unused sun8i_a23_r_pinctrl_desc = {
418         .functions      = sun8i_a23_r_pinctrl_functions,
419         .num_functions  = ARRAY_SIZE(sun8i_a23_r_pinctrl_functions),
420         .first_bank     = SUNXI_GPIO_L,
421         .num_banks      = 1,
422 };
423
424 static const struct sunxi_pinctrl_function sun8i_a33_pinctrl_functions[] = {
425         { "gpio_in",    0 },
426         { "gpio_out",   1 },
427         { "i2c0",       2 },    /* PH2-PH3 */
428         { "i2c1",       2 },    /* PH4-PH5 */
429         { "mmc0",       2 },    /* PF0-PF5 */
430         { "mmc1",       2 },    /* PG0-PG5 */
431         { "mmc2",       3 },    /* PC5-PC16 */
432         { "nand0",      2 },    /* PC0-PC16 */
433         { "spi0",       3 },    /* PC0-PC3 */
434 #if IS_ENABLED(CONFIG_UART0_PORT_F)
435         { "uart0",      3 },    /* PF2-PF4 */
436 #else
437         { "uart0",      3 },    /* PB0-PB1 */
438 #endif
439         { "uart1",      2 },    /* PG6-PG7 */
440         { "uart2",      2 },    /* PB0-PB1 */
441 };
442
443 static const struct sunxi_pinctrl_desc __maybe_unused sun8i_a33_pinctrl_desc = {
444         .functions      = sun8i_a33_pinctrl_functions,
445         .num_functions  = ARRAY_SIZE(sun8i_a33_pinctrl_functions),
446         .first_bank     = SUNXI_GPIO_A,
447         .num_banks      = 8,
448 };
449
450 static const struct sunxi_pinctrl_function sun8i_a83t_pinctrl_functions[] = {
451         { "gmac",       4 },    /* PD2-PD23 */
452         { "gpio_in",    0 },
453         { "gpio_out",   1 },
454         { "i2c0",       2 },    /* PH0-PH1 */
455         { "i2c1",       2 },    /* PH2-PH3 */
456         { "mmc0",       2 },    /* PF0-PF5 */
457         { "mmc1",       2 },    /* PG0-PG5 */
458         { "mmc2",       3 },    /* PC5-PC16 */
459         { "nand0",      2 },    /* PC0-PC18 */
460         { "spi0",       3 },    /* PC0-PC3 */
461 #if IS_ENABLED(CONFIG_UART0_PORT_F)
462         { "uart0",      3 },    /* PF2-PF4 */
463 #else
464         { "uart0",      2 },    /* PB9-PB10 */
465 #endif
466         { "uart1",      2 },    /* PG6-PG7 */
467         { "uart2",      2 },    /* PB0-PB1 */
468 };
469
470 static const struct sunxi_pinctrl_desc __maybe_unused sun8i_a83t_pinctrl_desc = {
471         .functions      = sun8i_a83t_pinctrl_functions,
472         .num_functions  = ARRAY_SIZE(sun8i_a83t_pinctrl_functions),
473         .first_bank     = SUNXI_GPIO_A,
474         .num_banks      = 8,
475 };
476
477 static const struct sunxi_pinctrl_function sun8i_a83t_r_pinctrl_functions[] = {
478         { "gpio_in",    0 },
479         { "gpio_out",   1 },
480         { "s_i2c",      2 },    /* PL8-PL9 */
481         { "s_rsb",      2 },    /* PL0-PL1 */
482         { "s_uart",     2 },    /* PL2-PL3 */
483 };
484
485 static const struct sunxi_pinctrl_desc __maybe_unused sun8i_a83t_r_pinctrl_desc = {
486         .functions      = sun8i_a83t_r_pinctrl_functions,
487         .num_functions  = ARRAY_SIZE(sun8i_a83t_r_pinctrl_functions),
488         .first_bank     = SUNXI_GPIO_L,
489         .num_banks      = 1,
490 };
491
492 static const struct sunxi_pinctrl_function sun8i_h3_pinctrl_functions[] = {
493         { "emac",       2 },    /* PD0-PD17 */
494         { "gpio_in",    0 },
495         { "gpio_out",   1 },
496         { "i2c0",       2 },    /* PA11-PA12 */
497         { "i2c1",       3 },    /* PA18-PA19 */
498         { "mmc0",       2 },    /* PF0-PF5 */
499         { "mmc1",       2 },    /* PG0-PG5 */
500         { "mmc2",       3 },    /* PC5-PC16 */
501         { "nand0",      2 },    /* PC0-PC16 */
502         { "spi0",       3 },    /* PC0-PC3 */
503 #if IS_ENABLED(CONFIG_UART0_PORT_F)
504         { "uart0",      3 },    /* PF2-PF4 */
505 #else
506         { "uart0",      2 },    /* PA4-PA5 */
507 #endif
508         { "uart1",      2 },    /* PG6-PG7 */
509         { "uart2",      2 },    /* PA0-PA1 */
510 };
511
512 static const struct sunxi_pinctrl_desc __maybe_unused sun8i_h3_pinctrl_desc = {
513         .functions      = sun8i_h3_pinctrl_functions,
514         .num_functions  = ARRAY_SIZE(sun8i_h3_pinctrl_functions),
515         .first_bank     = SUNXI_GPIO_A,
516         .num_banks      = 7,
517 };
518
519 static const struct sunxi_pinctrl_function sun8i_h3_r_pinctrl_functions[] = {
520         { "gpio_in",    0 },
521         { "gpio_out",   1 },
522         { "s_i2c",      2 },    /* PL0-PL1 */
523         { "s_uart",     2 },    /* PL2-PL3 */
524 };
525
526 static const struct sunxi_pinctrl_desc __maybe_unused sun8i_h3_r_pinctrl_desc = {
527         .functions      = sun8i_h3_r_pinctrl_functions,
528         .num_functions  = ARRAY_SIZE(sun8i_h3_r_pinctrl_functions),
529         .first_bank     = SUNXI_GPIO_L,
530         .num_banks      = 1,
531 };
532
533 static const struct sunxi_pinctrl_function sun8i_v3s_pinctrl_functions[] = {
534         { "emac",       4 },    /* PD0-PD17 */
535         { "gpio_in",    0 },
536         { "gpio_out",   1 },
537         { "i2c0",       2 },    /* PB6-PB7 */
538         { "i2c1",       2 },    /* PB8-PB9 */
539         { "mmc0",       2 },    /* PF0-PF5 */
540         { "mmc1",       2 },    /* PG0-PG5 */
541         { "mmc2",       2 },    /* PC0-PC10 */
542         { "spi0",       3 },    /* PC0-PC3 */
543 #if IS_ENABLED(CONFIG_UART0_PORT_F)
544         { "uart0",      3 },    /* PF2-PF4 */
545 #else
546         { "uart0",      3 },    /* PB8-PB9 */
547 #endif
548         { "uart1",      2 },    /* PG6-PG7 */
549         { "uart2",      2 },    /* PB0-PB1 */
550 };
551
552 static const struct sunxi_pinctrl_desc __maybe_unused sun8i_v3s_pinctrl_desc = {
553         .functions      = sun8i_v3s_pinctrl_functions,
554         .num_functions  = ARRAY_SIZE(sun8i_v3s_pinctrl_functions),
555         .first_bank     = SUNXI_GPIO_A,
556         .num_banks      = 7,
557 };
558
559 static const struct sunxi_pinctrl_function sun9i_a80_pinctrl_functions[] = {
560         { "gmac",       2 },    /* PA0-PA17 */
561         { "gpio_in",    0 },
562         { "gpio_out",   1 },
563         { "i2c0",       2 },    /* PH0-PH1 */
564         { "i2c1",       2 },    /* PH2-PH3 */
565         { "mmc0",       2 },    /* PF0-PF5 */
566         { "mmc1",       2 },    /* PG0-PG5 */
567         { "mmc2",       3 },    /* PC6-PC16 */
568         { "nand0",      2 },    /* PC0-PC18 */
569         { "spi0",       3 },    /* PC0-PC2, PC19 */
570 #if IS_ENABLED(CONFIG_UART0_PORT_F)
571         { "uart0",      4 },    /* PF2-PF4 */
572 #else
573         { "uart0",      2 },    /* PH12-PH13 */
574 #endif
575 };
576
577 static const struct sunxi_pinctrl_desc __maybe_unused sun9i_a80_pinctrl_desc = {
578         .functions      = sun9i_a80_pinctrl_functions,
579         .num_functions  = ARRAY_SIZE(sun9i_a80_pinctrl_functions),
580         .first_bank     = SUNXI_GPIO_A,
581         .num_banks      = 8,
582 };
583
584 static const struct sunxi_pinctrl_function sun9i_a80_r_pinctrl_functions[] = {
585         { "gpio_in",    0 },
586         { "gpio_out",   1 },
587         { "s_i2c0",     2 },    /* PN0-PN1 */
588         { "s_i2c1",     3 },    /* PM8-PM9 */
589         { "s_rsb",      3 },    /* PN0-PN1 */
590         { "s_uart",     3 },    /* PL0-PL1 */
591 };
592
593 static const struct sunxi_pinctrl_desc __maybe_unused sun9i_a80_r_pinctrl_desc = {
594         .functions      = sun9i_a80_r_pinctrl_functions,
595         .num_functions  = ARRAY_SIZE(sun9i_a80_r_pinctrl_functions),
596         .first_bank     = SUNXI_GPIO_L,
597         .num_banks      = 3,
598 };
599
600 static const struct sunxi_pinctrl_function sun50i_a64_pinctrl_functions[] = {
601         { "emac",       4 },    /* PD8-PD23 */
602         { "gpio_in",    0 },
603         { "gpio_out",   1 },
604         { "i2c0",       2 },    /* PH0-PH1 */
605         { "i2c1",       2 },    /* PH2-PH3 */
606         { "mmc0",       2 },    /* PF0-PF5 */
607         { "mmc1",       2 },    /* PG0-PG5 */
608         { "mmc2",       3 },    /* PC1-PC16 */
609         { "nand0",      2 },    /* PC0-PC16 */
610         { "pwm",        2 },    /* PD22 */
611         { "spi0",       4 },    /* PC0-PC3 */
612 #if IS_ENABLED(CONFIG_UART0_PORT_F)
613         { "uart0",      3 },    /* PF2-PF4 */
614 #else
615         { "uart0",      4 },    /* PB8-PB9 */
616 #endif
617         { "uart1",      2 },    /* PG6-PG7 */
618         { "uart2",      2 },    /* PB0-PB1 */
619 };
620
621 static const struct sunxi_pinctrl_desc __maybe_unused sun50i_a64_pinctrl_desc = {
622         .functions      = sun50i_a64_pinctrl_functions,
623         .num_functions  = ARRAY_SIZE(sun50i_a64_pinctrl_functions),
624         .first_bank     = SUNXI_GPIO_A,
625         .num_banks      = 8,
626 };
627
628 static const struct sunxi_pinctrl_function sun50i_a64_r_pinctrl_functions[] = {
629         { "gpio_in",    0 },
630         { "gpio_out",   1 },
631         { "s_i2c",      2 },    /* PL8-PL9 */
632         { "s_rsb",      2 },    /* PL0-PL1 */
633         { "s_uart",     2 },    /* PL2-PL3 */
634 };
635
636 static const struct sunxi_pinctrl_desc __maybe_unused sun50i_a64_r_pinctrl_desc = {
637         .functions      = sun50i_a64_r_pinctrl_functions,
638         .num_functions  = ARRAY_SIZE(sun50i_a64_r_pinctrl_functions),
639         .first_bank     = SUNXI_GPIO_L,
640         .num_banks      = 1,
641 };
642
643 static const struct sunxi_pinctrl_function sun50i_h5_pinctrl_functions[] = {
644         { "emac",       2 },    /* PD0-PD17 */
645         { "gpio_in",    0 },
646         { "gpio_out",   1 },
647         { "i2c0",       2 },    /* PA11-PA12 */
648         { "i2c1",       3 },    /* PA18-PA19 */
649         { "mmc0",       2 },    /* PF0-PF5 */
650         { "mmc1",       2 },    /* PG0-PG5 */
651         { "mmc2",       3 },    /* PC1-PC16 */
652         { "nand0",      2 },    /* PC0-PC16 */
653         { "spi0",       3 },    /* PC0-PC3 */
654 #if IS_ENABLED(CONFIG_UART0_PORT_F)
655         { "uart0",      3 },    /* PF2-PF4 */
656 #else
657         { "uart0",      2 },    /* PA4-PA5 */
658 #endif
659         { "uart1",      2 },    /* PG6-PG7 */
660         { "uart2",      2 },    /* PA0-PA1 */
661 };
662
663 static const struct sunxi_pinctrl_desc __maybe_unused sun50i_h5_pinctrl_desc = {
664         .functions      = sun50i_h5_pinctrl_functions,
665         .num_functions  = ARRAY_SIZE(sun50i_h5_pinctrl_functions),
666         .first_bank     = SUNXI_GPIO_A,
667         .num_banks      = 7,
668 };
669
670 static const struct sunxi_pinctrl_function sun50i_h6_pinctrl_functions[] = {
671         { "emac",       5 },    /* PD0-PD20 */
672         { "gpio_in",    0 },
673         { "gpio_out",   1 },
674         { "i2c0",       2 },    /* PD25-PD26 */
675         { "i2c1",       4 },    /* PH5-PH6 */
676         { "mmc0",       2 },    /* PF0-PF5 */
677         { "mmc1",       2 },    /* PG0-PG5 */
678         { "mmc2",       3 },    /* PC1-PC14 */
679         { "nand0",      2 },    /* PC0-PC16 */
680         { "spi0",       4 },    /* PC0-PC7 */
681 #if IS_ENABLED(CONFIG_UART0_PORT_F)
682         { "uart0",      3 },    /* PF2-PF4 */
683 #else
684         { "uart0",      2 },    /* PH0-PH1 */
685 #endif
686         { "uart1",      2 },    /* PG6-PG7 */
687 };
688
689 static const struct sunxi_pinctrl_desc __maybe_unused sun50i_h6_pinctrl_desc = {
690         .functions      = sun50i_h6_pinctrl_functions,
691         .num_functions  = ARRAY_SIZE(sun50i_h6_pinctrl_functions),
692         .first_bank     = SUNXI_GPIO_A,
693         .num_banks      = 8,
694 };
695
696 static const struct sunxi_pinctrl_function sun50i_h6_r_pinctrl_functions[] = {
697         { "gpio_in",    0 },
698         { "gpio_out",   1 },
699         { "s_i2c",      3 },    /* PL0-PL1 */
700         { "s_rsb",      2 },    /* PL0-PL1 */
701         { "s_uart",     2 },    /* PL2-PL3 */
702 };
703
704 static const struct sunxi_pinctrl_desc __maybe_unused sun50i_h6_r_pinctrl_desc = {
705         .functions      = sun50i_h6_r_pinctrl_functions,
706         .num_functions  = ARRAY_SIZE(sun50i_h6_r_pinctrl_functions),
707         .first_bank     = SUNXI_GPIO_L,
708         .num_banks      = 2,
709 };
710
711 static const struct sunxi_pinctrl_function sun50i_h616_pinctrl_functions[] = {
712         { "emac0",      2 },    /* PI0-PI16 */
713         { "gpio_in",    0 },
714         { "gpio_out",   1 },
715         { "mmc0",       2 },    /* PF0-PF5 */
716         { "mmc1",       2 },    /* PG0-PG5 */
717         { "mmc2",       3 },    /* PC0-PC16 */
718         { "nand0",      2 },    /* PC0-PC16 */
719         { "spi0",       4 },    /* PC0-PC7, PC15-PC16 */
720 #if IS_ENABLED(CONFIG_UART0_PORT_F)
721         { "uart0",      3 },    /* PF2-PF4 */
722 #else
723         { "uart0",      2 },    /* PH0-PH1 */
724 #endif
725         { "uart1",      2 },    /* PG6-PG7 */
726 };
727
728 static const struct sunxi_pinctrl_desc __maybe_unused sun50i_h616_pinctrl_desc = {
729         .functions      = sun50i_h616_pinctrl_functions,
730         .num_functions  = ARRAY_SIZE(sun50i_h616_pinctrl_functions),
731         .first_bank     = SUNXI_GPIO_A,
732         .num_banks      = 9,
733 };
734
735 static const struct sunxi_pinctrl_function sun50i_h616_r_pinctrl_functions[] = {
736         { "gpio_in",    0 },
737         { "gpio_out",   1 },
738         { "s_i2c",      3 },    /* PL0-PL1 */
739         { "s_rsb",      2 },    /* PL0-PL1 */
740         { "s_uart",     2 },    /* PL2-PL3 */
741 };
742
743 static const struct sunxi_pinctrl_desc __maybe_unused sun50i_h616_r_pinctrl_desc = {
744         .functions      = sun50i_h616_r_pinctrl_functions,
745         .num_functions  = ARRAY_SIZE(sun50i_h616_r_pinctrl_functions),
746         .first_bank     = SUNXI_GPIO_L,
747         .num_banks      = 1,
748 };
749
750 static const struct udevice_id sunxi_pinctrl_ids[] = {
751 #ifdef CONFIG_PINCTRL_SUNIV_F1C100S
752         {
753                 .compatible = "allwinner,suniv-f1c100s-pinctrl",
754                 .data = (ulong)&suniv_f1c100s_pinctrl_desc,
755         },
756 #endif
757 #ifdef CONFIG_PINCTRL_SUN4I_A10
758         {
759                 .compatible = "allwinner,sun4i-a10-pinctrl",
760                 .data = (ulong)&sun4i_a10_pinctrl_desc,
761         },
762 #endif
763 #ifdef CONFIG_PINCTRL_SUN5I_A13
764         {
765                 .compatible = "allwinner,sun5i-a10s-pinctrl",
766                 .data = (ulong)&sun5i_a13_pinctrl_desc,
767         },
768         {
769                 .compatible = "allwinner,sun5i-a13-pinctrl",
770                 .data = (ulong)&sun5i_a13_pinctrl_desc,
771         },
772 #endif
773 #ifdef CONFIG_PINCTRL_SUN6I_A31
774         {
775                 .compatible = "allwinner,sun6i-a31-pinctrl",
776                 .data = (ulong)&sun6i_a31_pinctrl_desc,
777         },
778         {
779                 .compatible = "allwinner,sun6i-a31s-pinctrl",
780                 .data = (ulong)&sun6i_a31_pinctrl_desc,
781         },
782 #endif
783 #ifdef CONFIG_PINCTRL_SUN6I_A31_R
784         {
785                 .compatible = "allwinner,sun6i-a31-r-pinctrl",
786                 .data = (ulong)&sun6i_a31_r_pinctrl_desc,
787         },
788 #endif
789 #ifdef CONFIG_PINCTRL_SUN7I_A20
790         {
791                 .compatible = "allwinner,sun7i-a20-pinctrl",
792                 .data = (ulong)&sun7i_a20_pinctrl_desc,
793         },
794 #endif
795 #ifdef CONFIG_PINCTRL_SUN8I_A23
796         {
797                 .compatible = "allwinner,sun8i-a23-pinctrl",
798                 .data = (ulong)&sun8i_a23_pinctrl_desc,
799         },
800 #endif
801 #ifdef CONFIG_PINCTRL_SUN8I_A23_R
802         {
803                 .compatible = "allwinner,sun8i-a23-r-pinctrl",
804                 .data = (ulong)&sun8i_a23_r_pinctrl_desc,
805         },
806 #endif
807 #ifdef CONFIG_PINCTRL_SUN8I_A33
808         {
809                 .compatible = "allwinner,sun8i-a33-pinctrl",
810                 .data = (ulong)&sun8i_a33_pinctrl_desc,
811         },
812 #endif
813 #ifdef CONFIG_PINCTRL_SUN8I_A83T
814         {
815                 .compatible = "allwinner,sun8i-a83t-pinctrl",
816                 .data = (ulong)&sun8i_a83t_pinctrl_desc,
817         },
818 #endif
819 #ifdef CONFIG_PINCTRL_SUN8I_A83T_R
820         {
821                 .compatible = "allwinner,sun8i-a83t-r-pinctrl",
822                 .data = (ulong)&sun8i_a83t_r_pinctrl_desc,
823         },
824 #endif
825 #ifdef CONFIG_PINCTRL_SUN8I_H3
826         {
827                 .compatible = "allwinner,sun8i-h3-pinctrl",
828                 .data = (ulong)&sun8i_h3_pinctrl_desc,
829         },
830 #endif
831 #ifdef CONFIG_PINCTRL_SUN8I_H3_R
832         {
833                 .compatible = "allwinner,sun8i-h3-r-pinctrl",
834                 .data = (ulong)&sun8i_h3_r_pinctrl_desc,
835         },
836 #endif
837 #ifdef CONFIG_PINCTRL_SUN7I_A20
838         {
839                 .compatible = "allwinner,sun8i-r40-pinctrl",
840                 .data = (ulong)&sun7i_a20_pinctrl_desc,
841         },
842 #endif
843 #ifdef CONFIG_PINCTRL_SUN8I_V3S
844         {
845                 .compatible = "allwinner,sun8i-v3-pinctrl",
846                 .data = (ulong)&sun8i_v3s_pinctrl_desc,
847         },
848         {
849                 .compatible = "allwinner,sun8i-v3s-pinctrl",
850                 .data = (ulong)&sun8i_v3s_pinctrl_desc,
851         },
852 #endif
853 #ifdef CONFIG_PINCTRL_SUN9I_A80
854         {
855                 .compatible = "allwinner,sun9i-a80-pinctrl",
856                 .data = (ulong)&sun9i_a80_pinctrl_desc,
857         },
858 #endif
859 #ifdef CONFIG_PINCTRL_SUN9I_A80_R
860         {
861                 .compatible = "allwinner,sun9i-a80-r-pinctrl",
862                 .data = (ulong)&sun9i_a80_r_pinctrl_desc,
863         },
864 #endif
865 #ifdef CONFIG_PINCTRL_SUN50I_A64
866         {
867                 .compatible = "allwinner,sun50i-a64-pinctrl",
868                 .data = (ulong)&sun50i_a64_pinctrl_desc,
869         },
870 #endif
871 #ifdef CONFIG_PINCTRL_SUN50I_A64_R
872         {
873                 .compatible = "allwinner,sun50i-a64-r-pinctrl",
874                 .data = (ulong)&sun50i_a64_r_pinctrl_desc,
875         },
876 #endif
877 #ifdef CONFIG_PINCTRL_SUN50I_H5
878         {
879                 .compatible = "allwinner,sun50i-h5-pinctrl",
880                 .data = (ulong)&sun50i_h5_pinctrl_desc,
881         },
882 #endif
883 #ifdef CONFIG_PINCTRL_SUN50I_H6
884         {
885                 .compatible = "allwinner,sun50i-h6-pinctrl",
886                 .data = (ulong)&sun50i_h6_pinctrl_desc,
887         },
888 #endif
889 #ifdef CONFIG_PINCTRL_SUN50I_H6_R
890         {
891                 .compatible = "allwinner,sun50i-h6-r-pinctrl",
892                 .data = (ulong)&sun50i_h6_r_pinctrl_desc,
893         },
894 #endif
895 #ifdef CONFIG_PINCTRL_SUN50I_H616
896         {
897                 .compatible = "allwinner,sun50i-h616-pinctrl",
898                 .data = (ulong)&sun50i_h616_pinctrl_desc,
899         },
900 #endif
901 #ifdef CONFIG_PINCTRL_SUN50I_H616_R
902         {
903                 .compatible = "allwinner,sun50i-h616-r-pinctrl",
904                 .data = (ulong)&sun50i_h616_r_pinctrl_desc,
905         },
906 #endif
907         {}
908 };
909
910 U_BOOT_DRIVER(sunxi_pinctrl) = {
911         .name           = "sunxi-pinctrl",
912         .id             = UCLASS_PINCTRL,
913         .of_match       = sunxi_pinctrl_ids,
914         .bind           = sunxi_pinctrl_bind,
915         .probe          = sunxi_pinctrl_probe,
916         .plat_auto      = sizeof(struct sunxi_pinctrl_plat),
917         .ops            = &sunxi_pinctrl_ops,
918 };