]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/arm/cpu/armv7/exynos/pinmux.c
zynq: add UART nodes to device tree to initialize UART with OF
[karo-tx-uboot.git] / arch / arm / cpu / armv7 / exynos / pinmux.c
1 /*
2  * Copyright (c) 2012 Samsung Electronics.
3  * Abhilash Kesavan <a.kesavan@samsung.com>
4  *
5  * SPDX-License-Identifier:     GPL-2.0+
6  */
7
8 #include <common.h>
9 #include <fdtdec.h>
10 #include <asm/arch/gpio.h>
11 #include <asm/arch/pinmux.h>
12 #include <asm/arch/sromc.h>
13
14 static void exynos5_uart_config(int peripheral)
15 {
16         struct exynos5_gpio_part1 *gpio1 =
17                 (struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1();
18         struct s5p_gpio_bank *bank;
19         int i, start, count;
20
21         switch (peripheral) {
22         case PERIPH_ID_UART0:
23                 bank = &gpio1->a0;
24                 start = 0;
25                 count = 4;
26                 break;
27         case PERIPH_ID_UART1:
28                 bank = &gpio1->d0;
29                 start = 0;
30                 count = 4;
31                 break;
32         case PERIPH_ID_UART2:
33                 bank = &gpio1->a1;
34                 start = 0;
35                 count = 4;
36                 break;
37         case PERIPH_ID_UART3:
38                 bank = &gpio1->a1;
39                 start = 4;
40                 count = 2;
41                 break;
42         default:
43                 debug("%s: invalid peripheral %d", __func__, peripheral);
44                 return;
45         }
46         for (i = start; i < start + count; i++) {
47                 s5p_gpio_set_pull(bank, i, GPIO_PULL_NONE);
48                 s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2));
49         }
50 }
51
52 static void exynos5420_uart_config(int peripheral)
53 {
54         struct exynos5420_gpio_part1 *gpio1 =
55                 (struct exynos5420_gpio_part1 *)samsung_get_base_gpio_part1();
56         struct s5p_gpio_bank *bank;
57         int i, start, count;
58
59         switch (peripheral) {
60         case PERIPH_ID_UART0:
61                 bank = &gpio1->a0;
62                 start = 0;
63                 count = 4;
64                 break;
65         case PERIPH_ID_UART1:
66                 bank = &gpio1->a0;
67                 start = 4;
68                 count = 4;
69                 break;
70         case PERIPH_ID_UART2:
71                 bank = &gpio1->a1;
72                 start = 0;
73                 count = 4;
74                 break;
75         case PERIPH_ID_UART3:
76                 bank = &gpio1->a1;
77                 start = 4;
78                 count = 2;
79                 break;
80         default:
81                 debug("%s: invalid peripheral %d", __func__, peripheral);
82                 return;
83         }
84
85         for (i = start; i < start + count; i++) {
86                 s5p_gpio_set_pull(bank, i, GPIO_PULL_NONE);
87                 s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2));
88         }
89 }
90
91 static int exynos5_mmc_config(int peripheral, int flags)
92 {
93         struct exynos5_gpio_part1 *gpio1 =
94                 (struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1();
95         struct s5p_gpio_bank *bank, *bank_ext;
96         int i, start = 0, gpio_func = 0;
97
98         switch (peripheral) {
99         case PERIPH_ID_SDMMC0:
100                 bank = &gpio1->c0;
101                 bank_ext = &gpio1->c1;
102                 start = 0;
103                 gpio_func = GPIO_FUNC(0x2);
104                 break;
105         case PERIPH_ID_SDMMC1:
106                 bank = &gpio1->c2;
107                 bank_ext = NULL;
108                 break;
109         case PERIPH_ID_SDMMC2:
110                 bank = &gpio1->c3;
111                 bank_ext = &gpio1->c4;
112                 start = 3;
113                 gpio_func = GPIO_FUNC(0x3);
114                 break;
115         case PERIPH_ID_SDMMC3:
116                 bank = &gpio1->c4;
117                 bank_ext = NULL;
118                 break;
119         default:
120                 debug("%s: invalid peripheral %d", __func__, peripheral);
121                 return -1;
122         }
123         if ((flags & PINMUX_FLAG_8BIT_MODE) && !bank_ext) {
124                 debug("SDMMC device %d does not support 8bit mode",
125                                 peripheral);
126                 return -1;
127         }
128         if (flags & PINMUX_FLAG_8BIT_MODE) {
129                 for (i = start; i <= (start + 3); i++) {
130                         s5p_gpio_cfg_pin(bank_ext, i, gpio_func);
131                         s5p_gpio_set_pull(bank_ext, i, GPIO_PULL_UP);
132                         s5p_gpio_set_drv(bank_ext, i, GPIO_DRV_4X);
133                 }
134         }
135         for (i = 0; i < 2; i++) {
136                 s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2));
137                 s5p_gpio_set_pull(bank, i, GPIO_PULL_NONE);
138                 s5p_gpio_set_drv(bank, i, GPIO_DRV_4X);
139         }
140         for (i = 3; i <= 6; i++) {
141                 s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2));
142                 s5p_gpio_set_pull(bank, i, GPIO_PULL_UP);
143                 s5p_gpio_set_drv(bank, i, GPIO_DRV_4X);
144         }
145
146         return 0;
147 }
148
149 static int exynos5420_mmc_config(int peripheral, int flags)
150 {
151         struct exynos5420_gpio_part3 *gpio3 =
152                 (struct exynos5420_gpio_part3 *)samsung_get_base_gpio_part3();
153         struct s5p_gpio_bank *bank = NULL, *bank_ext = NULL;
154         int i, start;
155
156         switch (peripheral) {
157         case PERIPH_ID_SDMMC0:
158                 bank = &gpio3->c0;
159                 bank_ext = &gpio3->c3;
160                 start = 0;
161                 break;
162         case PERIPH_ID_SDMMC1:
163                 bank = &gpio3->c1;
164                 bank_ext = &gpio3->d1;
165                 start = 4;
166                 break;
167         case PERIPH_ID_SDMMC2:
168                 bank = &gpio3->c2;
169                 bank_ext = NULL;
170                 start = 0;
171                 break;
172         default:
173                 start = 0;
174                 debug("%s: invalid peripheral %d", __func__, peripheral);
175                 return -1;
176         }
177
178         if ((flags & PINMUX_FLAG_8BIT_MODE) && !bank_ext) {
179                 debug("SDMMC device %d does not support 8bit mode",
180                       peripheral);
181                 return -1;
182         }
183
184         if (flags & PINMUX_FLAG_8BIT_MODE) {
185                 for (i = start; i <= (start + 3); i++) {
186                         s5p_gpio_cfg_pin(bank_ext, i, GPIO_FUNC(0x2));
187                         s5p_gpio_set_pull(bank_ext, i, GPIO_PULL_UP);
188                         s5p_gpio_set_drv(bank_ext, i, GPIO_DRV_4X);
189                 }
190         }
191
192         for (i = 0; i < 3; i++) {
193                 /*
194                  * MMC0 is intended to be used for eMMC. The
195                  * card detect pin is used as a VDDEN signal to
196                  * power on the eMMC. The 5420 iROM makes
197                  * this same assumption.
198                  */
199                 if ((peripheral == PERIPH_ID_SDMMC0) && (i == 2)) {
200                         s5p_gpio_set_value(bank, i, 1);
201                         s5p_gpio_cfg_pin(bank, i, GPIO_OUTPUT);
202                 } else {
203                         s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2));
204                 }
205                 s5p_gpio_set_pull(bank, i, GPIO_PULL_NONE);
206                 s5p_gpio_set_drv(bank, i, GPIO_DRV_4X);
207         }
208
209         for (i = 3; i <= 6; i++) {
210                 s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2));
211                 s5p_gpio_set_pull(bank, i, GPIO_PULL_UP);
212                 s5p_gpio_set_drv(bank, i, GPIO_DRV_4X);
213         }
214
215         return 0;
216 }
217
218 static void exynos5_sromc_config(int flags)
219 {
220         struct exynos5_gpio_part1 *gpio1 =
221                 (struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1();
222         int i;
223
224         /*
225          * SROM:CS1 and EBI
226          *
227          * GPY0[0]      SROM_CSn[0]
228          * GPY0[1]      SROM_CSn[1](2)
229          * GPY0[2]      SROM_CSn[2]
230          * GPY0[3]      SROM_CSn[3]
231          * GPY0[4]      EBI_OEn(2)
232          * GPY0[5]      EBI_EEn(2)
233          *
234          * GPY1[0]      EBI_BEn[0](2)
235          * GPY1[1]      EBI_BEn[1](2)
236          * GPY1[2]      SROM_WAIT(2)
237          * GPY1[3]      EBI_DATA_RDn(2)
238          */
239         s5p_gpio_cfg_pin(&gpio1->y0, (flags & PINMUX_FLAG_BANK),
240                                 GPIO_FUNC(2));
241         s5p_gpio_cfg_pin(&gpio1->y0, 4, GPIO_FUNC(2));
242         s5p_gpio_cfg_pin(&gpio1->y0, 5, GPIO_FUNC(2));
243
244         for (i = 0; i < 4; i++)
245                 s5p_gpio_cfg_pin(&gpio1->y1, i, GPIO_FUNC(2));
246
247         /*
248          * EBI: 8 Addrss Lines
249          *
250          * GPY3[0]      EBI_ADDR[0](2)
251          * GPY3[1]      EBI_ADDR[1](2)
252          * GPY3[2]      EBI_ADDR[2](2)
253          * GPY3[3]      EBI_ADDR[3](2)
254          * GPY3[4]      EBI_ADDR[4](2)
255          * GPY3[5]      EBI_ADDR[5](2)
256          * GPY3[6]      EBI_ADDR[6](2)
257          * GPY3[7]      EBI_ADDR[7](2)
258          *
259          * EBI: 16 Data Lines
260          *
261          * GPY5[0]      EBI_DATA[0](2)
262          * GPY5[1]      EBI_DATA[1](2)
263          * GPY5[2]      EBI_DATA[2](2)
264          * GPY5[3]      EBI_DATA[3](2)
265          * GPY5[4]      EBI_DATA[4](2)
266          * GPY5[5]      EBI_DATA[5](2)
267          * GPY5[6]      EBI_DATA[6](2)
268          * GPY5[7]      EBI_DATA[7](2)
269          *
270          * GPY6[0]      EBI_DATA[8](2)
271          * GPY6[1]      EBI_DATA[9](2)
272          * GPY6[2]      EBI_DATA[10](2)
273          * GPY6[3]      EBI_DATA[11](2)
274          * GPY6[4]      EBI_DATA[12](2)
275          * GPY6[5]      EBI_DATA[13](2)
276          * GPY6[6]      EBI_DATA[14](2)
277          * GPY6[7]      EBI_DATA[15](2)
278          */
279         for (i = 0; i < 8; i++) {
280                 s5p_gpio_cfg_pin(&gpio1->y3, i, GPIO_FUNC(2));
281                 s5p_gpio_set_pull(&gpio1->y3, i, GPIO_PULL_UP);
282
283                 s5p_gpio_cfg_pin(&gpio1->y5, i, GPIO_FUNC(2));
284                 s5p_gpio_set_pull(&gpio1->y5, i, GPIO_PULL_UP);
285
286                 s5p_gpio_cfg_pin(&gpio1->y6, i, GPIO_FUNC(2));
287                 s5p_gpio_set_pull(&gpio1->y6, i, GPIO_PULL_UP);
288         }
289 }
290
291 static void exynos5_i2c_config(int peripheral, int flags)
292 {
293
294         struct exynos5_gpio_part1 *gpio1 =
295                 (struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1();
296
297         switch (peripheral) {
298         case PERIPH_ID_I2C0:
299                 s5p_gpio_cfg_pin(&gpio1->b3, 0, GPIO_FUNC(0x2));
300                 s5p_gpio_cfg_pin(&gpio1->b3, 1, GPIO_FUNC(0x2));
301                 break;
302         case PERIPH_ID_I2C1:
303                 s5p_gpio_cfg_pin(&gpio1->b3, 2, GPIO_FUNC(0x2));
304                 s5p_gpio_cfg_pin(&gpio1->b3, 3, GPIO_FUNC(0x2));
305                 break;
306         case PERIPH_ID_I2C2:
307                 s5p_gpio_cfg_pin(&gpio1->a0, 6, GPIO_FUNC(0x3));
308                 s5p_gpio_cfg_pin(&gpio1->a0, 7, GPIO_FUNC(0x3));
309                 break;
310         case PERIPH_ID_I2C3:
311                 s5p_gpio_cfg_pin(&gpio1->a1, 2, GPIO_FUNC(0x3));
312                 s5p_gpio_cfg_pin(&gpio1->a1, 3, GPIO_FUNC(0x3));
313                 break;
314         case PERIPH_ID_I2C4:
315                 s5p_gpio_cfg_pin(&gpio1->a2, 0, GPIO_FUNC(0x3));
316                 s5p_gpio_cfg_pin(&gpio1->a2, 1, GPIO_FUNC(0x3));
317                 break;
318         case PERIPH_ID_I2C5:
319                 s5p_gpio_cfg_pin(&gpio1->a2, 2, GPIO_FUNC(0x3));
320                 s5p_gpio_cfg_pin(&gpio1->a2, 3, GPIO_FUNC(0x3));
321                 break;
322         case PERIPH_ID_I2C6:
323                 s5p_gpio_cfg_pin(&gpio1->b1, 3, GPIO_FUNC(0x4));
324                 s5p_gpio_cfg_pin(&gpio1->b1, 4, GPIO_FUNC(0x4));
325                 break;
326         case PERIPH_ID_I2C7:
327                 s5p_gpio_cfg_pin(&gpio1->b2, 2, GPIO_FUNC(0x3));
328                 s5p_gpio_cfg_pin(&gpio1->b2, 3, GPIO_FUNC(0x3));
329                 break;
330         }
331 }
332
333 static void exynos5420_i2c_config(int peripheral)
334 {
335         struct exynos5420_gpio_part1 *gpio1 =
336                 (struct exynos5420_gpio_part1 *)samsung_get_base_gpio_part1();
337
338         switch (peripheral) {
339         case PERIPH_ID_I2C0:
340                 s5p_gpio_cfg_pin(&gpio1->b3, 0, GPIO_FUNC(0x2));
341                 s5p_gpio_cfg_pin(&gpio1->b3, 1, GPIO_FUNC(0x2));
342                 break;
343         case PERIPH_ID_I2C1:
344                 s5p_gpio_cfg_pin(&gpio1->b3, 2, GPIO_FUNC(0x2));
345                 s5p_gpio_cfg_pin(&gpio1->b3, 3, GPIO_FUNC(0x2));
346                 break;
347         case PERIPH_ID_I2C2:
348                 s5p_gpio_cfg_pin(&gpio1->a0, 6, GPIO_FUNC(0x3));
349                 s5p_gpio_cfg_pin(&gpio1->a0, 7, GPIO_FUNC(0x3));
350                 break;
351         case PERIPH_ID_I2C3:
352                 s5p_gpio_cfg_pin(&gpio1->a1, 2, GPIO_FUNC(0x3));
353                 s5p_gpio_cfg_pin(&gpio1->a1, 3, GPIO_FUNC(0x3));
354                 break;
355         case PERIPH_ID_I2C4:
356                 s5p_gpio_cfg_pin(&gpio1->a2, 0, GPIO_FUNC(0x3));
357                 s5p_gpio_cfg_pin(&gpio1->a2, 1, GPIO_FUNC(0x3));
358                 break;
359         case PERIPH_ID_I2C5:
360                 s5p_gpio_cfg_pin(&gpio1->a2, 2, GPIO_FUNC(0x3));
361                 s5p_gpio_cfg_pin(&gpio1->a2, 3, GPIO_FUNC(0x3));
362                 break;
363         case PERIPH_ID_I2C6:
364                 s5p_gpio_cfg_pin(&gpio1->b1, 3, GPIO_FUNC(0x4));
365                 s5p_gpio_cfg_pin(&gpio1->b1, 4, GPIO_FUNC(0x4));
366                 break;
367         case PERIPH_ID_I2C7:
368                 s5p_gpio_cfg_pin(&gpio1->b2, 2, GPIO_FUNC(0x3));
369                 s5p_gpio_cfg_pin(&gpio1->b2, 3, GPIO_FUNC(0x3));
370                 break;
371         case PERIPH_ID_I2C8:
372                 s5p_gpio_cfg_pin(&gpio1->b3, 4, GPIO_FUNC(0x2));
373                 s5p_gpio_cfg_pin(&gpio1->b3, 5, GPIO_FUNC(0x2));
374                 break;
375         case PERIPH_ID_I2C9:
376                 s5p_gpio_cfg_pin(&gpio1->b3, 6, GPIO_FUNC(0x2));
377                 s5p_gpio_cfg_pin(&gpio1->b3, 7, GPIO_FUNC(0x2));
378                 break;
379         case PERIPH_ID_I2C10:
380                 s5p_gpio_cfg_pin(&gpio1->b4, 0, GPIO_FUNC(0x2));
381                 s5p_gpio_cfg_pin(&gpio1->b4, 1, GPIO_FUNC(0x2));
382                 break;
383         }
384 }
385
386 static void exynos5_i2s_config(int peripheral)
387 {
388         int i;
389         struct exynos5_gpio_part1 *gpio1 =
390                 (struct exynos5_gpio_part1 *)samsung_get_base_gpio_part1();
391         struct exynos5_gpio_part4 *gpio4 =
392                 (struct exynos5_gpio_part4 *)samsung_get_base_gpio_part4();
393
394         switch (peripheral) {
395         case PERIPH_ID_I2S0:
396                 for (i = 0; i < 5; i++)
397                         s5p_gpio_cfg_pin(&gpio4->z, i, GPIO_FUNC(0x02));
398                 break;
399         case PERIPH_ID_I2S1:
400                 for (i = 0; i < 5; i++)
401                         s5p_gpio_cfg_pin(&gpio1->b0, i, GPIO_FUNC(0x02));
402                 break;
403         }
404 }
405
406 void exynos5_spi_config(int peripheral)
407 {
408         int cfg = 0, pin = 0, i;
409         struct s5p_gpio_bank *bank = NULL;
410         struct exynos5_gpio_part1 *gpio1 =
411                 (struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1();
412         struct exynos5_gpio_part2 *gpio2 =
413                 (struct exynos5_gpio_part2 *) samsung_get_base_gpio_part2();
414
415         switch (peripheral) {
416         case PERIPH_ID_SPI0:
417                 bank = &gpio1->a2;
418                 cfg = GPIO_FUNC(0x2);
419                 pin = 0;
420                 break;
421         case PERIPH_ID_SPI1:
422                 bank = &gpio1->a2;
423                 cfg = GPIO_FUNC(0x2);
424                 pin = 4;
425                 break;
426         case PERIPH_ID_SPI2:
427                 bank = &gpio1->b1;
428                 cfg = GPIO_FUNC(0x5);
429                 pin = 1;
430                 break;
431         case PERIPH_ID_SPI3:
432                 bank = &gpio2->f1;
433                 cfg = GPIO_FUNC(0x2);
434                 pin = 0;
435                 break;
436         case PERIPH_ID_SPI4:
437                 for (i = 0; i < 2; i++) {
438                         s5p_gpio_cfg_pin(&gpio2->f0, i + 2, GPIO_FUNC(0x4));
439                         s5p_gpio_cfg_pin(&gpio2->e0, i + 4, GPIO_FUNC(0x4));
440                 }
441                 break;
442         }
443         if (peripheral != PERIPH_ID_SPI4) {
444                 for (i = pin; i < pin + 4; i++)
445                         s5p_gpio_cfg_pin(bank, i, cfg);
446         }
447 }
448
449 void exynos5420_spi_config(int peripheral)
450 {
451         int cfg, pin, i;
452         struct s5p_gpio_bank *bank = NULL;
453         struct exynos5420_gpio_part1 *gpio1 =
454                 (struct exynos5420_gpio_part1 *)samsung_get_base_gpio_part1();
455         struct exynos5420_gpio_part4 *gpio4 =
456                 (struct exynos5420_gpio_part4 *)samsung_get_base_gpio_part4();
457
458         switch (peripheral) {
459         case PERIPH_ID_SPI0:
460                 bank = &gpio1->a2;
461                 cfg = GPIO_FUNC(0x2);
462                 pin = 0;
463                 break;
464         case PERIPH_ID_SPI1:
465                 bank = &gpio1->a2;
466                 cfg = GPIO_FUNC(0x2);
467                 pin = 4;
468                 break;
469         case PERIPH_ID_SPI2:
470                 bank = &gpio1->b1;
471                 cfg = GPIO_FUNC(0x5);
472                 pin = 1;
473                 break;
474         case PERIPH_ID_SPI3:
475                 bank = &gpio4->f1;
476                 cfg = GPIO_FUNC(0x2);
477                 pin = 0;
478                 break;
479         case PERIPH_ID_SPI4:
480                 cfg = 0;
481                 pin = 0;
482                 break;
483         default:
484                 cfg = 0;
485                 pin = 0;
486                 debug("%s: invalid peripheral %d", __func__, peripheral);
487                 return;
488         }
489
490         if (peripheral != PERIPH_ID_SPI4) {
491                 for (i = pin; i < pin + 4; i++)
492                         s5p_gpio_cfg_pin(bank, i, cfg);
493         } else {
494                 for (i = 0; i < 2; i++) {
495                         s5p_gpio_cfg_pin(&gpio4->f0, i + 2, GPIO_FUNC(0x4));
496                         s5p_gpio_cfg_pin(&gpio4->e0, i + 4, GPIO_FUNC(0x4));
497                 }
498         }
499 }
500
501 static int exynos5_pinmux_config(int peripheral, int flags)
502 {
503         switch (peripheral) {
504         case PERIPH_ID_UART0:
505         case PERIPH_ID_UART1:
506         case PERIPH_ID_UART2:
507         case PERIPH_ID_UART3:
508                 exynos5_uart_config(peripheral);
509                 break;
510         case PERIPH_ID_SDMMC0:
511         case PERIPH_ID_SDMMC1:
512         case PERIPH_ID_SDMMC2:
513         case PERIPH_ID_SDMMC3:
514                 return exynos5_mmc_config(peripheral, flags);
515         case PERIPH_ID_SROMC:
516                 exynos5_sromc_config(flags);
517                 break;
518         case PERIPH_ID_I2C0:
519         case PERIPH_ID_I2C1:
520         case PERIPH_ID_I2C2:
521         case PERIPH_ID_I2C3:
522         case PERIPH_ID_I2C4:
523         case PERIPH_ID_I2C5:
524         case PERIPH_ID_I2C6:
525         case PERIPH_ID_I2C7:
526                 exynos5_i2c_config(peripheral, flags);
527                 break;
528         case PERIPH_ID_I2S0:
529         case PERIPH_ID_I2S1:
530                 exynos5_i2s_config(peripheral);
531                 break;
532         case PERIPH_ID_SPI0:
533         case PERIPH_ID_SPI1:
534         case PERIPH_ID_SPI2:
535         case PERIPH_ID_SPI3:
536         case PERIPH_ID_SPI4:
537                 exynos5_spi_config(peripheral);
538                 break;
539         default:
540                 debug("%s: invalid peripheral %d", __func__, peripheral);
541                 return -1;
542         }
543
544         return 0;
545 }
546
547 static int exynos5420_pinmux_config(int peripheral, int flags)
548 {
549         switch (peripheral) {
550         case PERIPH_ID_UART0:
551         case PERIPH_ID_UART1:
552         case PERIPH_ID_UART2:
553         case PERIPH_ID_UART3:
554                 exynos5420_uart_config(peripheral);
555                 break;
556         case PERIPH_ID_SDMMC0:
557         case PERIPH_ID_SDMMC1:
558         case PERIPH_ID_SDMMC2:
559         case PERIPH_ID_SDMMC3:
560                 return exynos5420_mmc_config(peripheral, flags);
561         case PERIPH_ID_SPI0:
562         case PERIPH_ID_SPI1:
563         case PERIPH_ID_SPI2:
564         case PERIPH_ID_SPI3:
565         case PERIPH_ID_SPI4:
566                 exynos5420_spi_config(peripheral);
567                 break;
568         case PERIPH_ID_I2C0:
569         case PERIPH_ID_I2C1:
570         case PERIPH_ID_I2C2:
571         case PERIPH_ID_I2C3:
572         case PERIPH_ID_I2C4:
573         case PERIPH_ID_I2C5:
574         case PERIPH_ID_I2C6:
575         case PERIPH_ID_I2C7:
576         case PERIPH_ID_I2C8:
577         case PERIPH_ID_I2C9:
578         case PERIPH_ID_I2C10:
579                 exynos5420_i2c_config(peripheral);
580                 break;
581         default:
582                 debug("%s: invalid peripheral %d", __func__, peripheral);
583                 return -1;
584         }
585
586         return 0;
587 }
588
589 static void exynos4_i2c_config(int peripheral, int flags)
590 {
591         struct exynos4_gpio_part1 *gpio1 =
592                 (struct exynos4_gpio_part1 *) samsung_get_base_gpio_part1();
593
594         switch (peripheral) {
595         case PERIPH_ID_I2C0:
596                 s5p_gpio_cfg_pin(&gpio1->d1, 0, GPIO_FUNC(0x2));
597                 s5p_gpio_cfg_pin(&gpio1->d1, 1, GPIO_FUNC(0x2));
598                 break;
599         case PERIPH_ID_I2C1:
600                 s5p_gpio_cfg_pin(&gpio1->d1, 2, GPIO_FUNC(0x2));
601                 s5p_gpio_cfg_pin(&gpio1->d1, 3, GPIO_FUNC(0x2));
602                 break;
603         case PERIPH_ID_I2C2:
604                 s5p_gpio_cfg_pin(&gpio1->a0, 6, GPIO_FUNC(0x3));
605                 s5p_gpio_cfg_pin(&gpio1->a0, 7, GPIO_FUNC(0x3));
606                 break;
607         case PERIPH_ID_I2C3:
608                 s5p_gpio_cfg_pin(&gpio1->a1, 2, GPIO_FUNC(0x3));
609                 s5p_gpio_cfg_pin(&gpio1->a1, 3, GPIO_FUNC(0x3));
610                 break;
611         case PERIPH_ID_I2C4:
612                 s5p_gpio_cfg_pin(&gpio1->b, 2, GPIO_FUNC(0x3));
613                 s5p_gpio_cfg_pin(&gpio1->b, 3, GPIO_FUNC(0x3));
614                 break;
615         case PERIPH_ID_I2C5:
616                 s5p_gpio_cfg_pin(&gpio1->b, 6, GPIO_FUNC(0x3));
617                 s5p_gpio_cfg_pin(&gpio1->b, 7, GPIO_FUNC(0x3));
618                 break;
619         case PERIPH_ID_I2C6:
620                 s5p_gpio_cfg_pin(&gpio1->c1, 3, GPIO_FUNC(0x4));
621                 s5p_gpio_cfg_pin(&gpio1->c1, 4, GPIO_FUNC(0x4));
622                 break;
623         case PERIPH_ID_I2C7:
624                 s5p_gpio_cfg_pin(&gpio1->d0, 2, GPIO_FUNC(0x3));
625                 s5p_gpio_cfg_pin(&gpio1->d0, 3, GPIO_FUNC(0x3));
626                 break;
627         }
628 }
629
630 static int exynos4_mmc_config(int peripheral, int flags)
631 {
632         struct exynos4_gpio_part2 *gpio2 =
633                 (struct exynos4_gpio_part2 *)samsung_get_base_gpio_part2();
634         struct s5p_gpio_bank *bank, *bank_ext;
635         int i;
636
637         switch (peripheral) {
638         case PERIPH_ID_SDMMC0:
639                 bank = &gpio2->k0;
640                 bank_ext = &gpio2->k1;
641                 break;
642         case PERIPH_ID_SDMMC2:
643                 bank = &gpio2->k2;
644                 bank_ext = &gpio2->k3;
645                 break;
646         default:
647                 return -1;
648         }
649         for (i = 0; i < 7; i++) {
650                 if (i == 2)
651                         continue;
652                 s5p_gpio_cfg_pin(bank, i,  GPIO_FUNC(0x2));
653                 s5p_gpio_set_pull(bank, i, GPIO_PULL_NONE);
654                 s5p_gpio_set_drv(bank, i, GPIO_DRV_4X);
655         }
656         if (flags & PINMUX_FLAG_8BIT_MODE) {
657                 for (i = 3; i < 7; i++) {
658                         s5p_gpio_cfg_pin(bank_ext, i,  GPIO_FUNC(0x3));
659                         s5p_gpio_set_pull(bank_ext, i, GPIO_PULL_NONE);
660                         s5p_gpio_set_drv(bank_ext, i, GPIO_DRV_4X);
661                 }
662         }
663
664         return 0;
665 }
666
667 static void exynos4_uart_config(int peripheral)
668 {
669         struct exynos4_gpio_part1 *gpio1 =
670                 (struct exynos4_gpio_part1 *)samsung_get_base_gpio_part1();
671         struct s5p_gpio_bank *bank;
672         int i, start, count;
673
674         switch (peripheral) {
675         case PERIPH_ID_UART0:
676                 bank = &gpio1->a0;
677                 start = 0;
678                 count = 4;
679                 break;
680         case PERIPH_ID_UART1:
681                 bank = &gpio1->a0;
682                 start = 4;
683                 count = 4;
684                 break;
685         case PERIPH_ID_UART2:
686                 bank = &gpio1->a1;
687                 start = 0;
688                 count = 4;
689                 break;
690         case PERIPH_ID_UART3:
691                 bank = &gpio1->a1;
692                 start = 4;
693                 count = 2;
694                 break;
695         default:
696                 debug("%s: invalid peripheral %d", __func__, peripheral);
697                 return;
698         }
699         for (i = start; i < start + count; i++) {
700                 s5p_gpio_set_pull(bank, i, GPIO_PULL_NONE);
701                 s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2));
702         }
703 }
704 static int exynos4_pinmux_config(int peripheral, int flags)
705 {
706         switch (peripheral) {
707         case PERIPH_ID_UART0:
708         case PERIPH_ID_UART1:
709         case PERIPH_ID_UART2:
710         case PERIPH_ID_UART3:
711                 exynos4_uart_config(peripheral);
712                 break;
713         case PERIPH_ID_I2C0:
714         case PERIPH_ID_I2C1:
715         case PERIPH_ID_I2C2:
716         case PERIPH_ID_I2C3:
717         case PERIPH_ID_I2C4:
718         case PERIPH_ID_I2C5:
719         case PERIPH_ID_I2C6:
720         case PERIPH_ID_I2C7:
721                 exynos4_i2c_config(peripheral, flags);
722                 break;
723         case PERIPH_ID_SDMMC0:
724         case PERIPH_ID_SDMMC2:
725                 return exynos4_mmc_config(peripheral, flags);
726         case PERIPH_ID_SDMMC1:
727         case PERIPH_ID_SDMMC3:
728         case PERIPH_ID_SDMMC4:
729                 debug("SDMMC device %d not implemented\n", peripheral);
730                 return -1;
731         default:
732                 debug("%s: invalid peripheral %d", __func__, peripheral);
733                 return -1;
734         }
735
736         return 0;
737 }
738
739 int exynos_pinmux_config(int peripheral, int flags)
740 {
741         if (cpu_is_exynos5()) {
742                 if (proid_is_exynos5420())
743                         return exynos5420_pinmux_config(peripheral, flags);
744                 else if (proid_is_exynos5250())
745                         return exynos5_pinmux_config(peripheral, flags);
746         } else if (cpu_is_exynos4()) {
747                 return exynos4_pinmux_config(peripheral, flags);
748         } else {
749                 debug("pinmux functionality not supported\n");
750         }
751
752         return -1;
753 }
754
755 #ifdef CONFIG_OF_CONTROL
756 static int exynos4_pinmux_decode_periph_id(const void *blob, int node)
757 {
758         int err;
759         u32 cell[3];
760
761         err = fdtdec_get_int_array(blob, node, "interrupts", cell,
762                                         ARRAY_SIZE(cell));
763         if (err) {
764                 debug(" invalid peripheral id\n");
765                 return PERIPH_ID_NONE;
766         }
767
768         return cell[1];
769 }
770
771 static int exynos5_pinmux_decode_periph_id(const void *blob, int node)
772 {
773         int err;
774         u32 cell[3];
775
776         err = fdtdec_get_int_array(blob, node, "interrupts", cell,
777                                         ARRAY_SIZE(cell));
778         if (err)
779                 return PERIPH_ID_NONE;
780
781         return cell[1];
782 }
783
784 int pinmux_decode_periph_id(const void *blob, int node)
785 {
786         if (cpu_is_exynos5())
787                 return  exynos5_pinmux_decode_periph_id(blob, node);
788         else if (cpu_is_exynos4())
789                 return  exynos4_pinmux_decode_periph_id(blob, node);
790         else
791                 return PERIPH_ID_NONE;
792 }
793 #endif