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