]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/arm/cpu/armv7/exynos/pinmux.c
Merge branch 'next' of git://git.denx.de/u-boot-mpc83xx
[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         }
43         for (i = start; i < start + count; i++) {
44                 s5p_gpio_set_pull(bank, i, GPIO_PULL_NONE);
45                 s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2));
46         }
47 }
48
49 static int exynos5_mmc_config(int peripheral, int flags)
50 {
51         struct exynos5_gpio_part1 *gpio1 =
52                 (struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1();
53         struct s5p_gpio_bank *bank, *bank_ext;
54         int i, start = 0, gpio_func = 0;
55
56         switch (peripheral) {
57         case PERIPH_ID_SDMMC0:
58                 bank = &gpio1->c0;
59                 bank_ext = &gpio1->c1;
60                 start = 0;
61                 gpio_func = GPIO_FUNC(0x2);
62                 break;
63         case PERIPH_ID_SDMMC1:
64                 bank = &gpio1->c2;
65                 bank_ext = NULL;
66                 break;
67         case PERIPH_ID_SDMMC2:
68                 bank = &gpio1->c3;
69                 bank_ext = &gpio1->c4;
70                 start = 3;
71                 gpio_func = GPIO_FUNC(0x3);
72                 break;
73         case PERIPH_ID_SDMMC3:
74                 bank = &gpio1->c4;
75                 bank_ext = NULL;
76                 break;
77         }
78         if ((flags & PINMUX_FLAG_8BIT_MODE) && !bank_ext) {
79                 debug("SDMMC device %d does not support 8bit mode",
80                                 peripheral);
81                 return -1;
82         }
83         if (flags & PINMUX_FLAG_8BIT_MODE) {
84                 for (i = start; i <= (start + 3); i++) {
85                         s5p_gpio_cfg_pin(bank_ext, i, gpio_func);
86                         s5p_gpio_set_pull(bank_ext, i, GPIO_PULL_UP);
87                         s5p_gpio_set_drv(bank_ext, i, GPIO_DRV_4X);
88                 }
89         }
90         for (i = 0; i < 2; i++) {
91                 s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2));
92                 s5p_gpio_set_pull(bank, i, GPIO_PULL_NONE);
93                 s5p_gpio_set_drv(bank, i, GPIO_DRV_4X);
94         }
95         for (i = 3; i <= 6; i++) {
96                 s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2));
97                 s5p_gpio_set_pull(bank, i, GPIO_PULL_UP);
98                 s5p_gpio_set_drv(bank, i, GPIO_DRV_4X);
99         }
100
101         return 0;
102 }
103
104 static void exynos5_sromc_config(int flags)
105 {
106         struct exynos5_gpio_part1 *gpio1 =
107                 (struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1();
108         int i;
109
110         /*
111          * SROM:CS1 and EBI
112          *
113          * GPY0[0]      SROM_CSn[0]
114          * GPY0[1]      SROM_CSn[1](2)
115          * GPY0[2]      SROM_CSn[2]
116          * GPY0[3]      SROM_CSn[3]
117          * GPY0[4]      EBI_OEn(2)
118          * GPY0[5]      EBI_EEn(2)
119          *
120          * GPY1[0]      EBI_BEn[0](2)
121          * GPY1[1]      EBI_BEn[1](2)
122          * GPY1[2]      SROM_WAIT(2)
123          * GPY1[3]      EBI_DATA_RDn(2)
124          */
125         s5p_gpio_cfg_pin(&gpio1->y0, (flags & PINMUX_FLAG_BANK),
126                                 GPIO_FUNC(2));
127         s5p_gpio_cfg_pin(&gpio1->y0, 4, GPIO_FUNC(2));
128         s5p_gpio_cfg_pin(&gpio1->y0, 5, GPIO_FUNC(2));
129
130         for (i = 0; i < 4; i++)
131                 s5p_gpio_cfg_pin(&gpio1->y1, i, GPIO_FUNC(2));
132
133         /*
134          * EBI: 8 Addrss Lines
135          *
136          * GPY3[0]      EBI_ADDR[0](2)
137          * GPY3[1]      EBI_ADDR[1](2)
138          * GPY3[2]      EBI_ADDR[2](2)
139          * GPY3[3]      EBI_ADDR[3](2)
140          * GPY3[4]      EBI_ADDR[4](2)
141          * GPY3[5]      EBI_ADDR[5](2)
142          * GPY3[6]      EBI_ADDR[6](2)
143          * GPY3[7]      EBI_ADDR[7](2)
144          *
145          * EBI: 16 Data Lines
146          *
147          * GPY5[0]      EBI_DATA[0](2)
148          * GPY5[1]      EBI_DATA[1](2)
149          * GPY5[2]      EBI_DATA[2](2)
150          * GPY5[3]      EBI_DATA[3](2)
151          * GPY5[4]      EBI_DATA[4](2)
152          * GPY5[5]      EBI_DATA[5](2)
153          * GPY5[6]      EBI_DATA[6](2)
154          * GPY5[7]      EBI_DATA[7](2)
155          *
156          * GPY6[0]      EBI_DATA[8](2)
157          * GPY6[1]      EBI_DATA[9](2)
158          * GPY6[2]      EBI_DATA[10](2)
159          * GPY6[3]      EBI_DATA[11](2)
160          * GPY6[4]      EBI_DATA[12](2)
161          * GPY6[5]      EBI_DATA[13](2)
162          * GPY6[6]      EBI_DATA[14](2)
163          * GPY6[7]      EBI_DATA[15](2)
164          */
165         for (i = 0; i < 8; i++) {
166                 s5p_gpio_cfg_pin(&gpio1->y3, i, GPIO_FUNC(2));
167                 s5p_gpio_set_pull(&gpio1->y3, i, GPIO_PULL_UP);
168
169                 s5p_gpio_cfg_pin(&gpio1->y5, i, GPIO_FUNC(2));
170                 s5p_gpio_set_pull(&gpio1->y5, i, GPIO_PULL_UP);
171
172                 s5p_gpio_cfg_pin(&gpio1->y6, i, GPIO_FUNC(2));
173                 s5p_gpio_set_pull(&gpio1->y6, i, GPIO_PULL_UP);
174         }
175 }
176
177 static void exynos5_i2c_config(int peripheral, int flags)
178 {
179
180         struct exynos5_gpio_part1 *gpio1 =
181                 (struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1();
182
183         switch (peripheral) {
184         case PERIPH_ID_I2C0:
185                 s5p_gpio_cfg_pin(&gpio1->b3, 0, GPIO_FUNC(0x2));
186                 s5p_gpio_cfg_pin(&gpio1->b3, 1, GPIO_FUNC(0x2));
187                 break;
188         case PERIPH_ID_I2C1:
189                 s5p_gpio_cfg_pin(&gpio1->b3, 2, GPIO_FUNC(0x2));
190                 s5p_gpio_cfg_pin(&gpio1->b3, 3, GPIO_FUNC(0x2));
191                 break;
192         case PERIPH_ID_I2C2:
193                 s5p_gpio_cfg_pin(&gpio1->a0, 6, GPIO_FUNC(0x3));
194                 s5p_gpio_cfg_pin(&gpio1->a0, 7, GPIO_FUNC(0x3));
195                 break;
196         case PERIPH_ID_I2C3:
197                 s5p_gpio_cfg_pin(&gpio1->a1, 2, GPIO_FUNC(0x3));
198                 s5p_gpio_cfg_pin(&gpio1->a1, 3, GPIO_FUNC(0x3));
199                 break;
200         case PERIPH_ID_I2C4:
201                 s5p_gpio_cfg_pin(&gpio1->a2, 0, GPIO_FUNC(0x3));
202                 s5p_gpio_cfg_pin(&gpio1->a2, 1, GPIO_FUNC(0x3));
203                 break;
204         case PERIPH_ID_I2C5:
205                 s5p_gpio_cfg_pin(&gpio1->a2, 2, GPIO_FUNC(0x3));
206                 s5p_gpio_cfg_pin(&gpio1->a2, 3, GPIO_FUNC(0x3));
207                 break;
208         case PERIPH_ID_I2C6:
209                 s5p_gpio_cfg_pin(&gpio1->b1, 3, GPIO_FUNC(0x4));
210                 s5p_gpio_cfg_pin(&gpio1->b1, 4, GPIO_FUNC(0x4));
211                 break;
212         case PERIPH_ID_I2C7:
213                 s5p_gpio_cfg_pin(&gpio1->b2, 2, GPIO_FUNC(0x3));
214                 s5p_gpio_cfg_pin(&gpio1->b2, 3, GPIO_FUNC(0x3));
215                 break;
216         }
217 }
218
219 static void exynos5_i2s_config(int peripheral)
220 {
221         int i;
222         struct exynos5_gpio_part1 *gpio1 =
223                 (struct exynos5_gpio_part1 *)samsung_get_base_gpio_part1();
224         struct exynos5_gpio_part4 *gpio4 =
225                 (struct exynos5_gpio_part4 *)samsung_get_base_gpio_part4();
226
227         switch (peripheral) {
228         case PERIPH_ID_I2S0:
229                 for (i = 0; i < 5; i++)
230                         s5p_gpio_cfg_pin(&gpio4->z, i, GPIO_FUNC(0x02));
231                 break;
232         case PERIPH_ID_I2S1:
233                 for (i = 0; i < 5; i++)
234                         s5p_gpio_cfg_pin(&gpio1->b0, i, GPIO_FUNC(0x02));
235                 break;
236         }
237 }
238
239 void exynos5_spi_config(int peripheral)
240 {
241         int cfg = 0, pin = 0, i;
242         struct s5p_gpio_bank *bank = NULL;
243         struct exynos5_gpio_part1 *gpio1 =
244                 (struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1();
245         struct exynos5_gpio_part2 *gpio2 =
246                 (struct exynos5_gpio_part2 *) samsung_get_base_gpio_part2();
247
248         switch (peripheral) {
249         case PERIPH_ID_SPI0:
250                 bank = &gpio1->a2;
251                 cfg = GPIO_FUNC(0x2);
252                 pin = 0;
253                 break;
254         case PERIPH_ID_SPI1:
255                 bank = &gpio1->a2;
256                 cfg = GPIO_FUNC(0x2);
257                 pin = 4;
258                 break;
259         case PERIPH_ID_SPI2:
260                 bank = &gpio1->b1;
261                 cfg = GPIO_FUNC(0x5);
262                 pin = 1;
263                 break;
264         case PERIPH_ID_SPI3:
265                 bank = &gpio2->f1;
266                 cfg = GPIO_FUNC(0x2);
267                 pin = 0;
268                 break;
269         case PERIPH_ID_SPI4:
270                 for (i = 0; i < 2; i++) {
271                         s5p_gpio_cfg_pin(&gpio2->f0, i + 2, GPIO_FUNC(0x4));
272                         s5p_gpio_cfg_pin(&gpio2->e0, i + 4, GPIO_FUNC(0x4));
273                 }
274                 break;
275         }
276         if (peripheral != PERIPH_ID_SPI4) {
277                 for (i = pin; i < pin + 4; i++)
278                         s5p_gpio_cfg_pin(bank, i, cfg);
279         }
280 }
281
282 static int exynos5_pinmux_config(int peripheral, int flags)
283 {
284         switch (peripheral) {
285         case PERIPH_ID_UART0:
286         case PERIPH_ID_UART1:
287         case PERIPH_ID_UART2:
288         case PERIPH_ID_UART3:
289                 exynos5_uart_config(peripheral);
290                 break;
291         case PERIPH_ID_SDMMC0:
292         case PERIPH_ID_SDMMC1:
293         case PERIPH_ID_SDMMC2:
294         case PERIPH_ID_SDMMC3:
295                 return exynos5_mmc_config(peripheral, flags);
296         case PERIPH_ID_SROMC:
297                 exynos5_sromc_config(flags);
298                 break;
299         case PERIPH_ID_I2C0:
300         case PERIPH_ID_I2C1:
301         case PERIPH_ID_I2C2:
302         case PERIPH_ID_I2C3:
303         case PERIPH_ID_I2C4:
304         case PERIPH_ID_I2C5:
305         case PERIPH_ID_I2C6:
306         case PERIPH_ID_I2C7:
307                 exynos5_i2c_config(peripheral, flags);
308                 break;
309         case PERIPH_ID_I2S0:
310         case PERIPH_ID_I2S1:
311                 exynos5_i2s_config(peripheral);
312                 break;
313         case PERIPH_ID_SPI0:
314         case PERIPH_ID_SPI1:
315         case PERIPH_ID_SPI2:
316         case PERIPH_ID_SPI3:
317         case PERIPH_ID_SPI4:
318                 exynos5_spi_config(peripheral);
319                 break;
320         default:
321                 debug("%s: invalid peripheral %d", __func__, peripheral);
322                 return -1;
323         }
324
325         return 0;
326 }
327
328 static void exynos4_i2c_config(int peripheral, int flags)
329 {
330         struct exynos4_gpio_part1 *gpio1 =
331                 (struct exynos4_gpio_part1 *) samsung_get_base_gpio_part1();
332
333         switch (peripheral) {
334         case PERIPH_ID_I2C0:
335                 s5p_gpio_cfg_pin(&gpio1->d1, 0, GPIO_FUNC(0x2));
336                 s5p_gpio_cfg_pin(&gpio1->d1, 1, GPIO_FUNC(0x2));
337                 break;
338         case PERIPH_ID_I2C1:
339                 s5p_gpio_cfg_pin(&gpio1->d1, 2, GPIO_FUNC(0x2));
340                 s5p_gpio_cfg_pin(&gpio1->d1, 3, GPIO_FUNC(0x2));
341                 break;
342         case PERIPH_ID_I2C2:
343                 s5p_gpio_cfg_pin(&gpio1->a0, 6, GPIO_FUNC(0x3));
344                 s5p_gpio_cfg_pin(&gpio1->a0, 7, GPIO_FUNC(0x3));
345                 break;
346         case PERIPH_ID_I2C3:
347                 s5p_gpio_cfg_pin(&gpio1->a1, 2, GPIO_FUNC(0x3));
348                 s5p_gpio_cfg_pin(&gpio1->a1, 3, GPIO_FUNC(0x3));
349                 break;
350         case PERIPH_ID_I2C4:
351                 s5p_gpio_cfg_pin(&gpio1->b, 2, GPIO_FUNC(0x3));
352                 s5p_gpio_cfg_pin(&gpio1->b, 3, GPIO_FUNC(0x3));
353                 break;
354         case PERIPH_ID_I2C5:
355                 s5p_gpio_cfg_pin(&gpio1->b, 6, GPIO_FUNC(0x3));
356                 s5p_gpio_cfg_pin(&gpio1->b, 7, GPIO_FUNC(0x3));
357                 break;
358         case PERIPH_ID_I2C6:
359                 s5p_gpio_cfg_pin(&gpio1->c1, 3, GPIO_FUNC(0x4));
360                 s5p_gpio_cfg_pin(&gpio1->c1, 4, GPIO_FUNC(0x4));
361                 break;
362         case PERIPH_ID_I2C7:
363                 s5p_gpio_cfg_pin(&gpio1->d0, 2, GPIO_FUNC(0x3));
364                 s5p_gpio_cfg_pin(&gpio1->d0, 3, GPIO_FUNC(0x3));
365                 break;
366         }
367 }
368
369 static int exynos4_mmc_config(int peripheral, int flags)
370 {
371         struct exynos4_gpio_part2 *gpio2 =
372                 (struct exynos4_gpio_part2 *)samsung_get_base_gpio_part2();
373         struct s5p_gpio_bank *bank, *bank_ext;
374         int i;
375
376         switch (peripheral) {
377         case PERIPH_ID_SDMMC0:
378                 bank = &gpio2->k0;
379                 bank_ext = &gpio2->k1;
380                 break;
381         case PERIPH_ID_SDMMC2:
382                 bank = &gpio2->k2;
383                 bank_ext = &gpio2->k3;
384                 break;
385         default:
386                 return -1;
387         }
388         for (i = 0; i < 7; i++) {
389                 if (i == 2)
390                         continue;
391                 s5p_gpio_cfg_pin(bank, i,  GPIO_FUNC(0x2));
392                 s5p_gpio_set_pull(bank, i, GPIO_PULL_NONE);
393                 s5p_gpio_set_drv(bank, i, GPIO_DRV_4X);
394         }
395         if (flags & PINMUX_FLAG_8BIT_MODE) {
396                 for (i = 3; i < 7; i++) {
397                         s5p_gpio_cfg_pin(bank_ext, i,  GPIO_FUNC(0x3));
398                         s5p_gpio_set_pull(bank_ext, i, GPIO_PULL_NONE);
399                         s5p_gpio_set_drv(bank_ext, i, GPIO_DRV_4X);
400                 }
401         }
402
403         return 0;
404 }
405
406 static void exynos4_uart_config(int peripheral)
407 {
408         struct exynos4_gpio_part1 *gpio1 =
409                 (struct exynos4_gpio_part1 *)samsung_get_base_gpio_part1();
410         struct s5p_gpio_bank *bank;
411         int i, start, count;
412
413         switch (peripheral) {
414         case PERIPH_ID_UART0:
415                 bank = &gpio1->a0;
416                 start = 0;
417                 count = 4;
418                 break;
419         case PERIPH_ID_UART1:
420                 bank = &gpio1->a0;
421                 start = 4;
422                 count = 4;
423                 break;
424         case PERIPH_ID_UART2:
425                 bank = &gpio1->a1;
426                 start = 0;
427                 count = 4;
428                 break;
429         case PERIPH_ID_UART3:
430                 bank = &gpio1->a1;
431                 start = 4;
432                 count = 2;
433                 break;
434         }
435         for (i = start; i < start + count; i++) {
436                 s5p_gpio_set_pull(bank, i, GPIO_PULL_NONE);
437                 s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2));
438         }
439 }
440 static int exynos4_pinmux_config(int peripheral, int flags)
441 {
442         switch (peripheral) {
443         case PERIPH_ID_UART0:
444         case PERIPH_ID_UART1:
445         case PERIPH_ID_UART2:
446         case PERIPH_ID_UART3:
447                 exynos4_uart_config(peripheral);
448                 break;
449         case PERIPH_ID_I2C0:
450         case PERIPH_ID_I2C1:
451         case PERIPH_ID_I2C2:
452         case PERIPH_ID_I2C3:
453         case PERIPH_ID_I2C4:
454         case PERIPH_ID_I2C5:
455         case PERIPH_ID_I2C6:
456         case PERIPH_ID_I2C7:
457                 exynos4_i2c_config(peripheral, flags);
458                 break;
459         case PERIPH_ID_SDMMC0:
460         case PERIPH_ID_SDMMC2:
461                 return exynos4_mmc_config(peripheral, flags);
462         case PERIPH_ID_SDMMC1:
463         case PERIPH_ID_SDMMC3:
464         case PERIPH_ID_SDMMC4:
465                 printf("SDMMC device %d not implemented\n", peripheral);
466                 return -1;
467         default:
468                 debug("%s: invalid peripheral %d", __func__, peripheral);
469                 return -1;
470         }
471
472         return 0;
473 }
474
475 int exynos_pinmux_config(int peripheral, int flags)
476 {
477         if (cpu_is_exynos5()) {
478                 return exynos5_pinmux_config(peripheral, flags);
479         } else if (cpu_is_exynos4()) {
480                 return exynos4_pinmux_config(peripheral, flags);
481         } else {
482                 debug("pinmux functionality not supported\n");
483                 return -1;
484         }
485 }
486
487 #ifdef CONFIG_OF_CONTROL
488 static int exynos5_pinmux_decode_periph_id(const void *blob, int node)
489 {
490         int err;
491         u32 cell[3];
492
493         err = fdtdec_get_int_array(blob, node, "interrupts", cell,
494                                         ARRAY_SIZE(cell));
495         if (err)
496                 return PERIPH_ID_NONE;
497
498         /* check for invalid peripheral id */
499         if ((PERIPH_ID_SDMMC4 > cell[1]) || (cell[1] < PERIPH_ID_UART0))
500                 return cell[1];
501
502         debug(" invalid peripheral id\n");
503         return PERIPH_ID_NONE;
504 }
505
506 int pinmux_decode_periph_id(const void *blob, int node)
507 {
508         if (cpu_is_exynos5())
509                 return  exynos5_pinmux_decode_periph_id(blob, node);
510         else
511                 return PERIPH_ID_NONE;
512 }
513 #endif