2 * Copyright (c) 2012 Samsung Electronics.
3 * Abhilash Kesavan <a.kesavan@samsung.com>
5 * SPDX-License-Identifier: GPL-2.0+
10 #include <asm/arch/gpio.h>
11 #include <asm/arch/pinmux.h>
12 #include <asm/arch/sromc.h>
14 static void exynos5_uart_config(int peripheral)
16 struct exynos5_gpio_part1 *gpio1 =
17 (struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1();
18 struct s5p_gpio_bank *bank;
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));
49 static void exynos5420_uart_config(int peripheral)
51 struct exynos5420_gpio_part1 *gpio1 =
52 (struct exynos5420_gpio_part1 *)samsung_get_base_gpio_part1();
53 struct s5p_gpio_bank *bank;
79 for (i = start; i < start + count; i++) {
80 s5p_gpio_set_pull(bank, i, GPIO_PULL_NONE);
81 s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2));
85 static int exynos5_mmc_config(int peripheral, int flags)
87 struct exynos5_gpio_part1 *gpio1 =
88 (struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1();
89 struct s5p_gpio_bank *bank, *bank_ext;
90 int i, start = 0, gpio_func = 0;
93 case PERIPH_ID_SDMMC0:
95 bank_ext = &gpio1->c1;
97 gpio_func = GPIO_FUNC(0x2);
99 case PERIPH_ID_SDMMC1:
103 case PERIPH_ID_SDMMC2:
105 bank_ext = &gpio1->c4;
107 gpio_func = GPIO_FUNC(0x3);
109 case PERIPH_ID_SDMMC3:
114 if ((flags & PINMUX_FLAG_8BIT_MODE) && !bank_ext) {
115 debug("SDMMC device %d does not support 8bit mode",
119 if (flags & PINMUX_FLAG_8BIT_MODE) {
120 for (i = start; i <= (start + 3); i++) {
121 s5p_gpio_cfg_pin(bank_ext, i, gpio_func);
122 s5p_gpio_set_pull(bank_ext, i, GPIO_PULL_UP);
123 s5p_gpio_set_drv(bank_ext, i, GPIO_DRV_4X);
126 for (i = 0; i < 2; i++) {
127 s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2));
128 s5p_gpio_set_pull(bank, i, GPIO_PULL_NONE);
129 s5p_gpio_set_drv(bank, i, GPIO_DRV_4X);
131 for (i = 3; i <= 6; i++) {
132 s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2));
133 s5p_gpio_set_pull(bank, i, GPIO_PULL_UP);
134 s5p_gpio_set_drv(bank, i, GPIO_DRV_4X);
140 static int exynos5420_mmc_config(int peripheral, int flags)
142 struct exynos5420_gpio_part3 *gpio3 =
143 (struct exynos5420_gpio_part3 *)samsung_get_base_gpio_part3();
144 struct s5p_gpio_bank *bank = NULL, *bank_ext = NULL;
147 switch (peripheral) {
148 case PERIPH_ID_SDMMC0:
150 bank_ext = &gpio3->c3;
153 case PERIPH_ID_SDMMC1:
155 bank_ext = &gpio3->d1;
158 case PERIPH_ID_SDMMC2:
165 debug("%s: invalid peripheral %d", __func__, peripheral);
169 if ((flags & PINMUX_FLAG_8BIT_MODE) && !bank_ext) {
170 debug("SDMMC device %d does not support 8bit mode",
175 if (flags & PINMUX_FLAG_8BIT_MODE) {
176 for (i = start; i <= (start + 3); i++) {
177 s5p_gpio_cfg_pin(bank_ext, i, GPIO_FUNC(0x2));
178 s5p_gpio_set_pull(bank_ext, i, GPIO_PULL_UP);
179 s5p_gpio_set_drv(bank_ext, i, GPIO_DRV_4X);
183 for (i = 0; i < 3; i++) {
185 * MMC0 is intended to be used for eMMC. The
186 * card detect pin is used as a VDDEN signal to
187 * power on the eMMC. The 5420 iROM makes
188 * this same assumption.
190 if ((peripheral == PERIPH_ID_SDMMC0) && (i == 2)) {
191 s5p_gpio_set_value(bank, i, 1);
192 s5p_gpio_cfg_pin(bank, i, GPIO_OUTPUT);
194 s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2));
196 s5p_gpio_set_pull(bank, i, GPIO_PULL_NONE);
197 s5p_gpio_set_drv(bank, i, GPIO_DRV_4X);
200 for (i = 3; i <= 6; i++) {
201 s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2));
202 s5p_gpio_set_pull(bank, i, GPIO_PULL_UP);
203 s5p_gpio_set_drv(bank, i, GPIO_DRV_4X);
209 static void exynos5_sromc_config(int flags)
211 struct exynos5_gpio_part1 *gpio1 =
212 (struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1();
218 * GPY0[0] SROM_CSn[0]
219 * GPY0[1] SROM_CSn[1](2)
220 * GPY0[2] SROM_CSn[2]
221 * GPY0[3] SROM_CSn[3]
225 * GPY1[0] EBI_BEn[0](2)
226 * GPY1[1] EBI_BEn[1](2)
227 * GPY1[2] SROM_WAIT(2)
228 * GPY1[3] EBI_DATA_RDn(2)
230 s5p_gpio_cfg_pin(&gpio1->y0, (flags & PINMUX_FLAG_BANK),
232 s5p_gpio_cfg_pin(&gpio1->y0, 4, GPIO_FUNC(2));
233 s5p_gpio_cfg_pin(&gpio1->y0, 5, GPIO_FUNC(2));
235 for (i = 0; i < 4; i++)
236 s5p_gpio_cfg_pin(&gpio1->y1, i, GPIO_FUNC(2));
239 * EBI: 8 Addrss Lines
241 * GPY3[0] EBI_ADDR[0](2)
242 * GPY3[1] EBI_ADDR[1](2)
243 * GPY3[2] EBI_ADDR[2](2)
244 * GPY3[3] EBI_ADDR[3](2)
245 * GPY3[4] EBI_ADDR[4](2)
246 * GPY3[5] EBI_ADDR[5](2)
247 * GPY3[6] EBI_ADDR[6](2)
248 * GPY3[7] EBI_ADDR[7](2)
252 * GPY5[0] EBI_DATA[0](2)
253 * GPY5[1] EBI_DATA[1](2)
254 * GPY5[2] EBI_DATA[2](2)
255 * GPY5[3] EBI_DATA[3](2)
256 * GPY5[4] EBI_DATA[4](2)
257 * GPY5[5] EBI_DATA[5](2)
258 * GPY5[6] EBI_DATA[6](2)
259 * GPY5[7] EBI_DATA[7](2)
261 * GPY6[0] EBI_DATA[8](2)
262 * GPY6[1] EBI_DATA[9](2)
263 * GPY6[2] EBI_DATA[10](2)
264 * GPY6[3] EBI_DATA[11](2)
265 * GPY6[4] EBI_DATA[12](2)
266 * GPY6[5] EBI_DATA[13](2)
267 * GPY6[6] EBI_DATA[14](2)
268 * GPY6[7] EBI_DATA[15](2)
270 for (i = 0; i < 8; i++) {
271 s5p_gpio_cfg_pin(&gpio1->y3, i, GPIO_FUNC(2));
272 s5p_gpio_set_pull(&gpio1->y3, i, GPIO_PULL_UP);
274 s5p_gpio_cfg_pin(&gpio1->y5, i, GPIO_FUNC(2));
275 s5p_gpio_set_pull(&gpio1->y5, i, GPIO_PULL_UP);
277 s5p_gpio_cfg_pin(&gpio1->y6, i, GPIO_FUNC(2));
278 s5p_gpio_set_pull(&gpio1->y6, i, GPIO_PULL_UP);
282 static void exynos5_i2c_config(int peripheral, int flags)
285 struct exynos5_gpio_part1 *gpio1 =
286 (struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1();
288 switch (peripheral) {
290 s5p_gpio_cfg_pin(&gpio1->b3, 0, GPIO_FUNC(0x2));
291 s5p_gpio_cfg_pin(&gpio1->b3, 1, GPIO_FUNC(0x2));
294 s5p_gpio_cfg_pin(&gpio1->b3, 2, GPIO_FUNC(0x2));
295 s5p_gpio_cfg_pin(&gpio1->b3, 3, GPIO_FUNC(0x2));
298 s5p_gpio_cfg_pin(&gpio1->a0, 6, GPIO_FUNC(0x3));
299 s5p_gpio_cfg_pin(&gpio1->a0, 7, GPIO_FUNC(0x3));
302 s5p_gpio_cfg_pin(&gpio1->a1, 2, GPIO_FUNC(0x3));
303 s5p_gpio_cfg_pin(&gpio1->a1, 3, GPIO_FUNC(0x3));
306 s5p_gpio_cfg_pin(&gpio1->a2, 0, GPIO_FUNC(0x3));
307 s5p_gpio_cfg_pin(&gpio1->a2, 1, GPIO_FUNC(0x3));
310 s5p_gpio_cfg_pin(&gpio1->a2, 2, GPIO_FUNC(0x3));
311 s5p_gpio_cfg_pin(&gpio1->a2, 3, GPIO_FUNC(0x3));
314 s5p_gpio_cfg_pin(&gpio1->b1, 3, GPIO_FUNC(0x4));
315 s5p_gpio_cfg_pin(&gpio1->b1, 4, GPIO_FUNC(0x4));
318 s5p_gpio_cfg_pin(&gpio1->b2, 2, GPIO_FUNC(0x3));
319 s5p_gpio_cfg_pin(&gpio1->b2, 3, GPIO_FUNC(0x3));
324 static void exynos5420_i2c_config(int peripheral)
326 struct exynos5420_gpio_part1 *gpio1 =
327 (struct exynos5420_gpio_part1 *)samsung_get_base_gpio_part1();
329 switch (peripheral) {
331 s5p_gpio_cfg_pin(&gpio1->b3, 0, GPIO_FUNC(0x2));
332 s5p_gpio_cfg_pin(&gpio1->b3, 1, GPIO_FUNC(0x2));
335 s5p_gpio_cfg_pin(&gpio1->b3, 2, GPIO_FUNC(0x2));
336 s5p_gpio_cfg_pin(&gpio1->b3, 3, GPIO_FUNC(0x2));
339 s5p_gpio_cfg_pin(&gpio1->a0, 6, GPIO_FUNC(0x3));
340 s5p_gpio_cfg_pin(&gpio1->a0, 7, GPIO_FUNC(0x3));
343 s5p_gpio_cfg_pin(&gpio1->a1, 2, GPIO_FUNC(0x3));
344 s5p_gpio_cfg_pin(&gpio1->a1, 3, GPIO_FUNC(0x3));
347 s5p_gpio_cfg_pin(&gpio1->a2, 0, GPIO_FUNC(0x3));
348 s5p_gpio_cfg_pin(&gpio1->a2, 1, GPIO_FUNC(0x3));
351 s5p_gpio_cfg_pin(&gpio1->a2, 2, GPIO_FUNC(0x3));
352 s5p_gpio_cfg_pin(&gpio1->a2, 3, GPIO_FUNC(0x3));
355 s5p_gpio_cfg_pin(&gpio1->b1, 3, GPIO_FUNC(0x4));
356 s5p_gpio_cfg_pin(&gpio1->b1, 4, GPIO_FUNC(0x4));
359 s5p_gpio_cfg_pin(&gpio1->b2, 2, GPIO_FUNC(0x3));
360 s5p_gpio_cfg_pin(&gpio1->b2, 3, GPIO_FUNC(0x3));
363 s5p_gpio_cfg_pin(&gpio1->b3, 4, GPIO_FUNC(0x2));
364 s5p_gpio_cfg_pin(&gpio1->b3, 5, GPIO_FUNC(0x2));
367 s5p_gpio_cfg_pin(&gpio1->b3, 6, GPIO_FUNC(0x2));
368 s5p_gpio_cfg_pin(&gpio1->b3, 7, GPIO_FUNC(0x2));
370 case PERIPH_ID_I2C10:
371 s5p_gpio_cfg_pin(&gpio1->b4, 0, GPIO_FUNC(0x2));
372 s5p_gpio_cfg_pin(&gpio1->b4, 1, GPIO_FUNC(0x2));
377 static void exynos5_i2s_config(int peripheral)
380 struct exynos5_gpio_part1 *gpio1 =
381 (struct exynos5_gpio_part1 *)samsung_get_base_gpio_part1();
382 struct exynos5_gpio_part4 *gpio4 =
383 (struct exynos5_gpio_part4 *)samsung_get_base_gpio_part4();
385 switch (peripheral) {
387 for (i = 0; i < 5; i++)
388 s5p_gpio_cfg_pin(&gpio4->z, i, GPIO_FUNC(0x02));
391 for (i = 0; i < 5; i++)
392 s5p_gpio_cfg_pin(&gpio1->b0, i, GPIO_FUNC(0x02));
397 void exynos5_spi_config(int peripheral)
399 int cfg = 0, pin = 0, i;
400 struct s5p_gpio_bank *bank = NULL;
401 struct exynos5_gpio_part1 *gpio1 =
402 (struct exynos5_gpio_part1 *) samsung_get_base_gpio_part1();
403 struct exynos5_gpio_part2 *gpio2 =
404 (struct exynos5_gpio_part2 *) samsung_get_base_gpio_part2();
406 switch (peripheral) {
409 cfg = GPIO_FUNC(0x2);
414 cfg = GPIO_FUNC(0x2);
419 cfg = GPIO_FUNC(0x5);
424 cfg = GPIO_FUNC(0x2);
428 for (i = 0; i < 2; i++) {
429 s5p_gpio_cfg_pin(&gpio2->f0, i + 2, GPIO_FUNC(0x4));
430 s5p_gpio_cfg_pin(&gpio2->e0, i + 4, GPIO_FUNC(0x4));
434 if (peripheral != PERIPH_ID_SPI4) {
435 for (i = pin; i < pin + 4; i++)
436 s5p_gpio_cfg_pin(bank, i, cfg);
440 void exynos5420_spi_config(int peripheral)
443 struct s5p_gpio_bank *bank = NULL;
444 struct exynos5420_gpio_part1 *gpio1 =
445 (struct exynos5420_gpio_part1 *)samsung_get_base_gpio_part1();
446 struct exynos5420_gpio_part4 *gpio4 =
447 (struct exynos5420_gpio_part4 *)samsung_get_base_gpio_part4();
449 switch (peripheral) {
452 cfg = GPIO_FUNC(0x2);
457 cfg = GPIO_FUNC(0x2);
462 cfg = GPIO_FUNC(0x5);
467 cfg = GPIO_FUNC(0x2);
477 debug("%s: invalid peripheral %d", __func__, peripheral);
481 if (peripheral != PERIPH_ID_SPI4) {
482 for (i = pin; i < pin + 4; i++)
483 s5p_gpio_cfg_pin(bank, i, cfg);
485 for (i = 0; i < 2; i++) {
486 s5p_gpio_cfg_pin(&gpio4->f0, i + 2, GPIO_FUNC(0x4));
487 s5p_gpio_cfg_pin(&gpio4->e0, i + 4, GPIO_FUNC(0x4));
492 static int exynos5_pinmux_config(int peripheral, int flags)
494 switch (peripheral) {
495 case PERIPH_ID_UART0:
496 case PERIPH_ID_UART1:
497 case PERIPH_ID_UART2:
498 case PERIPH_ID_UART3:
499 exynos5_uart_config(peripheral);
501 case PERIPH_ID_SDMMC0:
502 case PERIPH_ID_SDMMC1:
503 case PERIPH_ID_SDMMC2:
504 case PERIPH_ID_SDMMC3:
505 return exynos5_mmc_config(peripheral, flags);
506 case PERIPH_ID_SROMC:
507 exynos5_sromc_config(flags);
517 exynos5_i2c_config(peripheral, flags);
521 exynos5_i2s_config(peripheral);
528 exynos5_spi_config(peripheral);
531 debug("%s: invalid peripheral %d", __func__, peripheral);
538 static int exynos5420_pinmux_config(int peripheral, int flags)
540 switch (peripheral) {
541 case PERIPH_ID_UART0:
542 case PERIPH_ID_UART1:
543 case PERIPH_ID_UART2:
544 case PERIPH_ID_UART3:
545 exynos5420_uart_config(peripheral);
547 case PERIPH_ID_SDMMC0:
548 case PERIPH_ID_SDMMC1:
549 case PERIPH_ID_SDMMC2:
550 case PERIPH_ID_SDMMC3:
551 return exynos5420_mmc_config(peripheral, flags);
557 exynos5420_spi_config(peripheral);
569 case PERIPH_ID_I2C10:
570 exynos5420_i2c_config(peripheral);
573 debug("%s: invalid peripheral %d", __func__, peripheral);
580 static void exynos4_i2c_config(int peripheral, int flags)
582 struct exynos4_gpio_part1 *gpio1 =
583 (struct exynos4_gpio_part1 *) samsung_get_base_gpio_part1();
585 switch (peripheral) {
587 s5p_gpio_cfg_pin(&gpio1->d1, 0, GPIO_FUNC(0x2));
588 s5p_gpio_cfg_pin(&gpio1->d1, 1, GPIO_FUNC(0x2));
591 s5p_gpio_cfg_pin(&gpio1->d1, 2, GPIO_FUNC(0x2));
592 s5p_gpio_cfg_pin(&gpio1->d1, 3, GPIO_FUNC(0x2));
595 s5p_gpio_cfg_pin(&gpio1->a0, 6, GPIO_FUNC(0x3));
596 s5p_gpio_cfg_pin(&gpio1->a0, 7, GPIO_FUNC(0x3));
599 s5p_gpio_cfg_pin(&gpio1->a1, 2, GPIO_FUNC(0x3));
600 s5p_gpio_cfg_pin(&gpio1->a1, 3, GPIO_FUNC(0x3));
603 s5p_gpio_cfg_pin(&gpio1->b, 2, GPIO_FUNC(0x3));
604 s5p_gpio_cfg_pin(&gpio1->b, 3, GPIO_FUNC(0x3));
607 s5p_gpio_cfg_pin(&gpio1->b, 6, GPIO_FUNC(0x3));
608 s5p_gpio_cfg_pin(&gpio1->b, 7, GPIO_FUNC(0x3));
611 s5p_gpio_cfg_pin(&gpio1->c1, 3, GPIO_FUNC(0x4));
612 s5p_gpio_cfg_pin(&gpio1->c1, 4, GPIO_FUNC(0x4));
615 s5p_gpio_cfg_pin(&gpio1->d0, 2, GPIO_FUNC(0x3));
616 s5p_gpio_cfg_pin(&gpio1->d0, 3, GPIO_FUNC(0x3));
621 static int exynos4_mmc_config(int peripheral, int flags)
623 struct exynos4_gpio_part2 *gpio2 =
624 (struct exynos4_gpio_part2 *)samsung_get_base_gpio_part2();
625 struct s5p_gpio_bank *bank, *bank_ext;
628 switch (peripheral) {
629 case PERIPH_ID_SDMMC0:
631 bank_ext = &gpio2->k1;
633 case PERIPH_ID_SDMMC2:
635 bank_ext = &gpio2->k3;
640 for (i = 0; i < 7; i++) {
643 s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2));
644 s5p_gpio_set_pull(bank, i, GPIO_PULL_NONE);
645 s5p_gpio_set_drv(bank, i, GPIO_DRV_4X);
647 if (flags & PINMUX_FLAG_8BIT_MODE) {
648 for (i = 3; i < 7; i++) {
649 s5p_gpio_cfg_pin(bank_ext, i, GPIO_FUNC(0x3));
650 s5p_gpio_set_pull(bank_ext, i, GPIO_PULL_NONE);
651 s5p_gpio_set_drv(bank_ext, i, GPIO_DRV_4X);
658 static void exynos4_uart_config(int peripheral)
660 struct exynos4_gpio_part1 *gpio1 =
661 (struct exynos4_gpio_part1 *)samsung_get_base_gpio_part1();
662 struct s5p_gpio_bank *bank;
665 switch (peripheral) {
666 case PERIPH_ID_UART0:
671 case PERIPH_ID_UART1:
676 case PERIPH_ID_UART2:
681 case PERIPH_ID_UART3:
687 for (i = start; i < start + count; i++) {
688 s5p_gpio_set_pull(bank, i, GPIO_PULL_NONE);
689 s5p_gpio_cfg_pin(bank, i, GPIO_FUNC(0x2));
692 static int exynos4_pinmux_config(int peripheral, int flags)
694 switch (peripheral) {
695 case PERIPH_ID_UART0:
696 case PERIPH_ID_UART1:
697 case PERIPH_ID_UART2:
698 case PERIPH_ID_UART3:
699 exynos4_uart_config(peripheral);
709 exynos4_i2c_config(peripheral, flags);
711 case PERIPH_ID_SDMMC0:
712 case PERIPH_ID_SDMMC2:
713 return exynos4_mmc_config(peripheral, flags);
714 case PERIPH_ID_SDMMC1:
715 case PERIPH_ID_SDMMC3:
716 case PERIPH_ID_SDMMC4:
717 debug("SDMMC device %d not implemented\n", peripheral);
720 debug("%s: invalid peripheral %d", __func__, peripheral);
727 int exynos_pinmux_config(int peripheral, int flags)
729 if (cpu_is_exynos5()) {
730 if (proid_is_exynos5420())
731 return exynos5420_pinmux_config(peripheral, flags);
732 else if (proid_is_exynos5250())
733 return exynos5_pinmux_config(peripheral, flags);
734 } else if (cpu_is_exynos4()) {
735 return exynos4_pinmux_config(peripheral, flags);
737 debug("pinmux functionality not supported\n");
743 #ifdef CONFIG_OF_CONTROL
744 static int exynos5_pinmux_decode_periph_id(const void *blob, int node)
749 err = fdtdec_get_int_array(blob, node, "interrupts", cell,
752 return PERIPH_ID_NONE;
754 /* check for invalid peripheral id */
755 if ((PERIPH_ID_SDMMC4 > cell[1]) || (cell[1] < PERIPH_ID_UART0))
758 debug(" invalid peripheral id\n");
759 return PERIPH_ID_NONE;
762 int pinmux_decode_periph_id(const void *blob, int node)
764 if (cpu_is_exynos5())
765 return exynos5_pinmux_decode_periph_id(blob, node);
767 return PERIPH_ID_NONE;