]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/arm/cpu/armv7/exynos/pinmux.c
Add GPL-2.0+ SPDX-License-Identifier to source files
[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
225         for (i = 0; i < 5; i++)
226                 s5p_gpio_cfg_pin(&gpio1->b0, i, GPIO_FUNC(0x02));
227 }
228
229 void exynos5_spi_config(int peripheral)
230 {
231         int cfg = 0, pin = 0, i;
232         struct s5p_gpio_bank *bank = NULL;
233         struct exynos5_gpio_part1 *gpio1 =
234                 (struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1();
235         struct exynos5_gpio_part2 *gpio2 =
236                 (struct exynos5_gpio_part2 *) samsung_get_base_gpio_part2();
237
238         switch (peripheral) {
239         case PERIPH_ID_SPI0:
240                 bank = &gpio1->a2;
241                 cfg = GPIO_FUNC(0x2);
242                 pin = 0;
243                 break;
244         case PERIPH_ID_SPI1:
245                 bank = &gpio1->a2;
246                 cfg = GPIO_FUNC(0x2);
247                 pin = 4;
248                 break;
249         case PERIPH_ID_SPI2:
250                 bank = &gpio1->b1;
251                 cfg = GPIO_FUNC(0x5);
252                 pin = 1;
253                 break;
254         case PERIPH_ID_SPI3:
255                 bank = &gpio2->f1;
256                 cfg = GPIO_FUNC(0x2);
257                 pin = 0;
258                 break;
259         case PERIPH_ID_SPI4:
260                 for (i = 0; i < 2; i++) {
261                         s5p_gpio_cfg_pin(&gpio2->f0, i + 2, GPIO_FUNC(0x4));
262                         s5p_gpio_cfg_pin(&gpio2->e0, i + 4, GPIO_FUNC(0x4));
263                 }
264                 break;
265         }
266         if (peripheral != PERIPH_ID_SPI4) {
267                 for (i = pin; i < pin + 4; i++)
268                         s5p_gpio_cfg_pin(bank, i, cfg);
269         }
270 }
271
272 static int exynos5_pinmux_config(int peripheral, int flags)
273 {
274         switch (peripheral) {
275         case PERIPH_ID_UART0:
276         case PERIPH_ID_UART1:
277         case PERIPH_ID_UART2:
278         case PERIPH_ID_UART3:
279                 exynos5_uart_config(peripheral);
280                 break;
281         case PERIPH_ID_SDMMC0:
282         case PERIPH_ID_SDMMC1:
283         case PERIPH_ID_SDMMC2:
284         case PERIPH_ID_SDMMC3:
285                 return exynos5_mmc_config(peripheral, flags);
286         case PERIPH_ID_SROMC:
287                 exynos5_sromc_config(flags);
288                 break;
289         case PERIPH_ID_I2C0:
290         case PERIPH_ID_I2C1:
291         case PERIPH_ID_I2C2:
292         case PERIPH_ID_I2C3:
293         case PERIPH_ID_I2C4:
294         case PERIPH_ID_I2C5:
295         case PERIPH_ID_I2C6:
296         case PERIPH_ID_I2C7:
297                 exynos5_i2c_config(peripheral, flags);
298                 break;
299         case PERIPH_ID_I2S1:
300                 exynos5_i2s_config(peripheral);
301                 break;
302         case PERIPH_ID_SPI0:
303         case PERIPH_ID_SPI1:
304         case PERIPH_ID_SPI2:
305         case PERIPH_ID_SPI3:
306         case PERIPH_ID_SPI4:
307                 exynos5_spi_config(peripheral);
308                 break;
309         default:
310                 debug("%s: invalid peripheral %d", __func__, peripheral);
311                 return -1;
312         }
313
314         return 0;
315 }
316
317 static void exynos4_i2c_config(int peripheral, int flags)
318 {
319         struct exynos4_gpio_part1 *gpio1 =
320                 (struct exynos4_gpio_part1 *) samsung_get_base_gpio_part1();
321
322         switch (peripheral) {
323         case PERIPH_ID_I2C0:
324                 s5p_gpio_cfg_pin(&gpio1->d1, 0, GPIO_FUNC(0x2));
325                 s5p_gpio_cfg_pin(&gpio1->d1, 1, GPIO_FUNC(0x2));
326                 break;
327         case PERIPH_ID_I2C1:
328                 s5p_gpio_cfg_pin(&gpio1->d1, 2, GPIO_FUNC(0x2));
329                 s5p_gpio_cfg_pin(&gpio1->d1, 3, GPIO_FUNC(0x2));
330                 break;
331         case PERIPH_ID_I2C2:
332                 s5p_gpio_cfg_pin(&gpio1->a0, 6, GPIO_FUNC(0x3));
333                 s5p_gpio_cfg_pin(&gpio1->a0, 7, GPIO_FUNC(0x3));
334                 break;
335         case PERIPH_ID_I2C3:
336                 s5p_gpio_cfg_pin(&gpio1->a1, 2, GPIO_FUNC(0x3));
337                 s5p_gpio_cfg_pin(&gpio1->a1, 3, GPIO_FUNC(0x3));
338                 break;
339         case PERIPH_ID_I2C4:
340                 s5p_gpio_cfg_pin(&gpio1->b, 2, GPIO_FUNC(0x3));
341                 s5p_gpio_cfg_pin(&gpio1->b, 3, GPIO_FUNC(0x3));
342                 break;
343         case PERIPH_ID_I2C5:
344                 s5p_gpio_cfg_pin(&gpio1->b, 6, GPIO_FUNC(0x3));
345                 s5p_gpio_cfg_pin(&gpio1->b, 7, GPIO_FUNC(0x3));
346                 break;
347         case PERIPH_ID_I2C6:
348                 s5p_gpio_cfg_pin(&gpio1->c1, 3, GPIO_FUNC(0x4));
349                 s5p_gpio_cfg_pin(&gpio1->c1, 4, GPIO_FUNC(0x4));
350                 break;
351         case PERIPH_ID_I2C7:
352                 s5p_gpio_cfg_pin(&gpio1->d0, 2, GPIO_FUNC(0x3));
353                 s5p_gpio_cfg_pin(&gpio1->d0, 3, GPIO_FUNC(0x3));
354                 break;
355         }
356 }
357
358 static int exynos4_mmc_config(int peripheral, int flags)
359 {
360         struct exynos4_gpio_part2 *gpio2 =
361                 (struct exynos4_gpio_part2 *)samsung_get_base_gpio_part2();
362         struct s5p_gpio_bank *bank, *bank_ext;
363         int i;
364
365         switch (peripheral) {
366         case PERIPH_ID_SDMMC0:
367                 bank = &gpio2->k0;
368                 bank_ext = &gpio2->k1;
369                 break;
370         case PERIPH_ID_SDMMC2:
371                 bank = &gpio2->k2;
372                 bank_ext = &gpio2->k3;
373                 break;
374         default:
375                 return -1;
376         }
377         for (i = 0; i < 7; i++) {
378                 if (i == 2)
379                         continue;
380                 s5p_gpio_cfg_pin(bank, i,  GPIO_FUNC(0x2));
381                 s5p_gpio_set_pull(bank, i, GPIO_PULL_NONE);
382                 s5p_gpio_set_drv(bank, i, GPIO_DRV_4X);
383         }
384         if (flags & PINMUX_FLAG_8BIT_MODE) {
385                 for (i = 3; i < 7; i++) {
386                         s5p_gpio_cfg_pin(bank_ext, i,  GPIO_FUNC(0x3));
387                         s5p_gpio_set_pull(bank_ext, i, GPIO_PULL_NONE);
388                         s5p_gpio_set_drv(bank_ext, i, GPIO_DRV_4X);
389                 }
390         }
391
392         return 0;
393 }
394
395 static void exynos4_uart_config(int peripheral)
396 {
397         struct exynos4_gpio_part1 *gpio1 =
398                 (struct exynos4_gpio_part1 *)samsung_get_base_gpio_part1();
399         struct s5p_gpio_bank *bank;
400         int i, start, count;
401
402         switch (peripheral) {
403         case PERIPH_ID_UART0:
404                 bank = &gpio1->a0;
405                 start = 0;
406                 count = 4;
407                 break;
408         case PERIPH_ID_UART1:
409                 bank = &gpio1->a0;
410                 start = 4;
411                 count = 4;
412                 break;
413         case PERIPH_ID_UART2:
414                 bank = &gpio1->a1;
415                 start = 0;
416                 count = 4;
417                 break;
418         case PERIPH_ID_UART3:
419                 bank = &gpio1->a1;
420                 start = 4;
421                 count = 2;
422                 break;
423         }
424         for (i = start; i < start + count; i++) {
425                 s5p_gpio_set_pull(bank, i, GPIO_PULL_NONE);
426                 s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2));
427         }
428 }
429 static int exynos4_pinmux_config(int peripheral, int flags)
430 {
431         switch (peripheral) {
432         case PERIPH_ID_UART0:
433         case PERIPH_ID_UART1:
434         case PERIPH_ID_UART2:
435         case PERIPH_ID_UART3:
436                 exynos4_uart_config(peripheral);
437                 break;
438         case PERIPH_ID_I2C0:
439         case PERIPH_ID_I2C1:
440         case PERIPH_ID_I2C2:
441         case PERIPH_ID_I2C3:
442         case PERIPH_ID_I2C4:
443         case PERIPH_ID_I2C5:
444         case PERIPH_ID_I2C6:
445         case PERIPH_ID_I2C7:
446                 exynos4_i2c_config(peripheral, flags);
447                 break;
448         case PERIPH_ID_SDMMC0:
449         case PERIPH_ID_SDMMC2:
450                 return exynos4_mmc_config(peripheral, flags);
451         case PERIPH_ID_SDMMC1:
452         case PERIPH_ID_SDMMC3:
453         case PERIPH_ID_SDMMC4:
454                 printf("SDMMC device %d not implemented\n", peripheral);
455                 return -1;
456         default:
457                 debug("%s: invalid peripheral %d", __func__, peripheral);
458                 return -1;
459         }
460
461         return 0;
462 }
463
464 int exynos_pinmux_config(int peripheral, int flags)
465 {
466         if (cpu_is_exynos5())
467                 return exynos5_pinmux_config(peripheral, flags);
468         else if (cpu_is_exynos4())
469                 return exynos4_pinmux_config(peripheral, flags);
470         else {
471                 debug("pinmux functionality not supported\n");
472                 return -1;
473         }
474 }
475
476 #ifdef CONFIG_OF_CONTROL
477 static int exynos5_pinmux_decode_periph_id(const void *blob, int node)
478 {
479         int err;
480         u32 cell[3];
481
482         err = fdtdec_get_int_array(blob, node, "interrupts", cell,
483                                         ARRAY_SIZE(cell));
484         if (err)
485                 return PERIPH_ID_NONE;
486
487         /* check for invalid peripheral id */
488         if ((PERIPH_ID_SDMMC4 > cell[1]) || (cell[1] < PERIPH_ID_UART0))
489                 return cell[1];
490
491         debug(" invalid peripheral id\n");
492         return PERIPH_ID_NONE;
493 }
494
495 int pinmux_decode_periph_id(const void *blob, int node)
496 {
497         if (cpu_is_exynos5())
498                 return  exynos5_pinmux_decode_periph_id(blob, node);
499         else
500                 return PERIPH_ID_NONE;
501 }
502 #endif