[U-Boot] [PATCH v5] Exynos5: Pinmux: Add fdt for pinmux
Akshay Saraswat
akshay.s at samsung.com
Thu Mar 7 15:09:35 CET 2013
This patch adds fdt nodes for peripherals which require
pin muxing and configuration. Device tree bindings for pinctrl
are kept same as required for Linux. Existing pinmux code
modified to retrieve gpio range and function related info from fdt.
Depends-on: [U-Boot] [PATCH 0/4 V3] EXYNOS5: Add GPIO numbering feature
URL: http://lists.denx.de/pipermail/u-boot/2013-February/146151.html
Signed-off-by: Akshay Saraswat <akshay.s at samsung.com>
---
Changes since v1:
- Device tree bindings changed to linux style.
- Added documentation for samsung pinctrl.
Changes since v2:
- Rebased as per new version of GPIO numbering patch-set.
Changes since v3:
- Added comments to reduce ambiguity and increase readability.
- Fixed few other nits.
Changes since v4:
- Added support for reading peripheral pinctrl subnode names from preipheral's node instead of hard coding.
arch/arm/cpu/armv7/exynos/pinmux.c | 357 +++++++-------
arch/arm/dts/exynos5250-pinctrl.dtsi | 675 +++++++++++++++++++++++++++
arch/arm/dts/exynos5250.dtsi | 92 ++++
board/samsung/dts/exynos5250-smdk5250.dts | 11 +
doc/device-tree-bindings/samsung-pinctrl.txt | 253 ++++++++++
include/fdtdec.h | 4 +
lib/fdtdec.c | 4 +
7 files changed, 1231 insertions(+), 165 deletions(-)
create mode 100644 arch/arm/dts/exynos5250-pinctrl.dtsi
create mode 100644 doc/device-tree-bindings/samsung-pinctrl.txt
diff --git a/arch/arm/cpu/armv7/exynos/pinmux.c b/arch/arm/cpu/armv7/exynos/pinmux.c
index a01ce0c..119db82 100644
--- a/arch/arm/cpu/armv7/exynos/pinmux.c
+++ b/arch/arm/cpu/armv7/exynos/pinmux.c
@@ -23,10 +23,20 @@
#include <common.h>
#include <fdtdec.h>
+#include <linux/ctype.h>
#include <asm/arch/gpio.h>
#include <asm/arch/pinmux.h>
#include <asm/arch/sromc.h>
+DECLARE_GLOBAL_DATA_PTR;
+
+/* Struct for temporarily storing pin related info */
+struct pin_group {
+ uint8_t function; /* Pin function */
+ uint8_t pull_mode; /* Pin pull mode */
+ uint8_t drive_strength; /* Pin drive strength */
+};
+
struct gpio_name_num_table exynos5_gpio_table[] = {
{ 'a', GPIO_A00 },
{ 'b', GPIO_B00 },
@@ -42,252 +52,271 @@ struct gpio_name_num_table exynos5_gpio_table[] = {
{ 'z', GPIO_Z0 },
};
-static void exynos5_uart_config(int peripheral)
+/* Extract and set pins in a particular pinctrl node */
+static void pinmux_set_pins(const char *fprop_data,
+ struct pin_group *pingrp)
{
- int i, start, count;
+ int i;
+ char gpio[5];
+
+ /*
+ * Get all the pin names from fdt and fill the gpio array
+ * with corresponding enum values(Pin numbers).
+ */
+ for (i = 0; !(fprop_data[i] == (int)NULL &&
+ fprop_data[i+1] == (int)NULL); i += 7) {
+ int pin_num = -1;
+
+ /*
+ * Modify pin name retrieved from fdt,
+ * so that name_to_gpio may understand.
+ */
+ gpio[0] = fprop_data[i];
+ gpio[1] = fprop_data[i + 1];
+ gpio[2] = fprop_data[i + 2];
+ gpio[3] = fprop_data[i + 3];
+ gpio[4] = fprop_data[i + 5];
+
+ pin_num = name_to_gpio(gpio);
+
+ /*
+ * If pin number is valid, add it to the pin array
+ * and increment pin count.
+ */
+ if (pin_num >= 0) {
+ gpio_cfg_pin(pin_num,
+ S5P_GPIO_FUNC(pingrp->function));
+ gpio_set_pull(pin_num, pingrp->pull_mode);
+ gpio_set_drv(pin_num, pingrp->drive_strength);
+ }
+ }
+}
+
+/* Extract all the config info from pinctrl periph subnodei */
+static int pinmux_do_config(struct pin_group *pingrp, const char * dev_name)
+{
+ int node, subnode;
+ const char *fprop_data;
+
+ /* Loop for all pinctrl nodes in fdt */
+ for (node = fdtdec_next_compatible(gd->fdt_blob, 0,
+ COMPAT_SAMSUNG_PINCTRL); node >= 0;
+ node = fdtdec_next_compatible(gd->fdt_blob, node,
+ COMPAT_SAMSUNG_PINCTRL)) {
+ /* Get the subnode from FDT for this peripheral*/
+ subnode = fdt_subnode_offset(gd->fdt_blob,
+ node, dev_name);
+ if (subnode < 0)
+ continue;
+
+ /* Get names of pins to be configured from fdt */
+ fprop_data = fdt_getprop(gd->fdt_blob,
+ subnode, "samsung,pins", NULL);
+
+ /* Get the pin function from fdt */
+ pingrp->function = fdtdec_get_int(gd->fdt_blob,
+ subnode, "samsung,pin-function", 0);
+
+ /* Get the pull mode for pins from fdt */
+ pingrp->pull_mode = fdtdec_get_int(gd->fdt_blob,
+ subnode, "samsung,pin-pud", 0);
+
+ /* Get the drive strength for pins from fdt */
+ pingrp->drive_strength = fdtdec_get_int(gd->fdt_blob,
+ subnode, "samsung,pin-drv", 0);
+
+ /* Convert pin names to pin numbers */
+ pinmux_set_pins(fprop_data, pingrp);
+
+ return 0;
+ }
+
+ return -1;
+}
+
+/* Set configuration for all pins as per fdt for a peripheral */
+static int pinmux_group_set(struct pin_group *pingrp, int pnode)
+{
+ int err, i = 0;
+ const char *fprop_data;
+ const char *dev_name;
+
+ fprop_data = fdt_getprop(gd->fdt_blob, pnode,
+ "samsung,pinctrl-names", NULL);
+
+ do {
+ dev_name = (fprop_data + i);
+ err = pinmux_do_config(pingrp, dev_name);
+ if (err)
+ break;
+ while (fprop_data[i] != (int)NULL)
+ i++;
+ } while (isalnum(fprop_data[++i]));
+
+ return err;
+}
+
+static int exynos5_uart_config(int peripheral)
+{
+ int suffix, pnode;
+ struct pin_group pingrp;
switch (peripheral) {
case PERIPH_ID_UART0:
- start = GPIO_A00;
- count = 4;
+ suffix = 0;
break;
case PERIPH_ID_UART1:
- start = GPIO_D00;
- count = 4;
+ suffix = 1;
break;
case PERIPH_ID_UART2:
- start = GPIO_A10;
- count = 4;
+ suffix = 2;
break;
case PERIPH_ID_UART3:
- start = GPIO_A14;
- count = 2;
+ suffix = 3;
break;
}
- for (i = start; i < start + count; i++) {
- gpio_set_pull(i, S5P_GPIO_PULL_NONE);
- gpio_cfg_pin(i, S5P_GPIO_FUNC(0x2));
- }
+
+ pnode = fdtdec_next_alias(gd->fdt_blob, "uart",
+ COMPAT_SAMSUNG_EXYNOS_UART, &suffix);
+
+ return pinmux_group_set(&pingrp, pnode);
}
-static int exynos5_mmc_config(int peripheral, int flags)
+static int exynos5_mmc_config(int peripheral)
{
- int i, start, start_ext, gpio_func = 0;
+ int suffix, pnode;
+ struct pin_group pingrp;
switch (peripheral) {
case PERIPH_ID_SDMMC0:
- start = GPIO_C00;
- start_ext = GPIO_C10;
- gpio_func = S5P_GPIO_FUNC(0x2);
+ suffix = 0;
break;
case PERIPH_ID_SDMMC1:
- start = GPIO_C20;
- start_ext = 0;
+ suffix = 1;
break;
case PERIPH_ID_SDMMC2:
- start = GPIO_C30;
- start_ext = GPIO_C43;
- gpio_func = S5P_GPIO_FUNC(0x3);
+ suffix = 2;
break;
case PERIPH_ID_SDMMC3:
- start = GPIO_C40;
- start_ext = 0;
+ suffix = 3;
break;
}
- if ((flags & PINMUX_FLAG_8BIT_MODE) && !start_ext) {
- debug("SDMMC device %d does not support 8bit mode",
- peripheral);
- return -1;
- }
- if (flags & PINMUX_FLAG_8BIT_MODE) {
- for (i = start_ext; i <= (start_ext + 3); i++) {
- gpio_cfg_pin(i, gpio_func);
- gpio_set_pull(i, S5P_GPIO_PULL_UP);
- gpio_set_drv(i, S5P_GPIO_DRV_4X);
- }
- }
- for (i = 0; i < 2; i++) {
- gpio_cfg_pin(start + i, S5P_GPIO_FUNC(0x2));
- gpio_set_pull(start + i, S5P_GPIO_PULL_NONE);
- gpio_set_drv(start + i, S5P_GPIO_DRV_4X);
- }
- for (i = 3; i <= 6; i++) {
- gpio_cfg_pin(start + i, S5P_GPIO_FUNC(0x2));
- gpio_set_pull(start + i, S5P_GPIO_PULL_UP);
- gpio_set_drv(start + i, S5P_GPIO_DRV_4X);
- }
- return 0;
+ pnode = fdtdec_next_alias(gd->fdt_blob, "mshc",
+ COMPAT_SAMSUNG_EXYNOS_MSHC, &suffix);
+
+ return pinmux_group_set(&pingrp, pnode);
}
-static void exynos5_sromc_config(int flags)
+static int exynos5_sromc_config(void)
{
- int i;
-
- /*
- * SROM:CS1 and EBI
- *
- * GPY0[0] SROM_CSn[0]
- * GPY0[1] SROM_CSn[1](2)
- * GPY0[2] SROM_CSn[2]
- * GPY0[3] SROM_CSn[3]
- * GPY0[4] EBI_OEn(2)
- * GPY0[5] EBI_EEn(2)
- *
- * GPY1[0] EBI_BEn[0](2)
- * GPY1[1] EBI_BEn[1](2)
- * GPY1[2] SROM_WAIT(2)
- * GPY1[3] EBI_DATA_RDn(2)
- */
- gpio_cfg_pin(GPIO_Y00 + (flags & PINMUX_FLAG_BANK),
- S5P_GPIO_FUNC(2));
- gpio_cfg_pin(GPIO_Y04, S5P_GPIO_FUNC(2));
- gpio_cfg_pin(GPIO_Y05, S5P_GPIO_FUNC(2));
-
- for (i = 0; i < 4; i++)
- gpio_cfg_pin(GPIO_Y10 + i, S5P_GPIO_FUNC(2));
-
- /*
- * EBI: 8 Addrss Lines
- *
- * GPY3[0] EBI_ADDR[0](2)
- * GPY3[1] EBI_ADDR[1](2)
- * GPY3[2] EBI_ADDR[2](2)
- * GPY3[3] EBI_ADDR[3](2)
- * GPY3[4] EBI_ADDR[4](2)
- * GPY3[5] EBI_ADDR[5](2)
- * GPY3[6] EBI_ADDR[6](2)
- * GPY3[7] EBI_ADDR[7](2)
- *
- * EBI: 16 Data Lines
- *
- * GPY5[0] EBI_DATA[0](2)
- * GPY5[1] EBI_DATA[1](2)
- * GPY5[2] EBI_DATA[2](2)
- * GPY5[3] EBI_DATA[3](2)
- * GPY5[4] EBI_DATA[4](2)
- * GPY5[5] EBI_DATA[5](2)
- * GPY5[6] EBI_DATA[6](2)
- * GPY5[7] EBI_DATA[7](2)
- *
- * GPY6[0] EBI_DATA[8](2)
- * GPY6[1] EBI_DATA[9](2)
- * GPY6[2] EBI_DATA[10](2)
- * GPY6[3] EBI_DATA[11](2)
- * GPY6[4] EBI_DATA[12](2)
- * GPY6[5] EBI_DATA[13](2)
- * GPY6[6] EBI_DATA[14](2)
- * GPY6[7] EBI_DATA[15](2)
- */
- for (i = 0; i < 8; i++) {
- gpio_cfg_pin(GPIO_Y30 + i, S5P_GPIO_FUNC(2));
- gpio_set_pull(GPIO_Y30 + i, S5P_GPIO_PULL_UP);
+ int pnode;
+ static struct pin_group pingrp;
- gpio_cfg_pin(GPIO_Y50 + i, S5P_GPIO_FUNC(2));
- gpio_set_pull(GPIO_Y50 + i, S5P_GPIO_PULL_UP);
+ pnode = fdtdec_next_compatible(gd->fdt_blob, 0,
+ COMPAT_SAMSUNG_EXYNOS5_SROMC);
- gpio_cfg_pin(GPIO_Y60 + i, S5P_GPIO_FUNC(2));
- gpio_set_pull(GPIO_Y60 + i, S5P_GPIO_PULL_UP);
- }
+ return pinmux_group_set(&pingrp, pnode);
}
-static void exynos5_i2c_config(int peripheral, int flags)
+static int exynos5_i2c_config(int peripheral)
{
+ int suffix, pnode;
+ struct pin_group pingrp;
switch (peripheral) {
case PERIPH_ID_I2C0:
- gpio_cfg_pin(GPIO_B30, S5P_GPIO_FUNC(0x2));
- gpio_cfg_pin(GPIO_B31, S5P_GPIO_FUNC(0x2));
+ suffix = 0;
break;
case PERIPH_ID_I2C1:
- gpio_cfg_pin(GPIO_B32, S5P_GPIO_FUNC(0x2));
- gpio_cfg_pin(GPIO_B33, S5P_GPIO_FUNC(0x2));
+ suffix = 1;
break;
case PERIPH_ID_I2C2:
- gpio_cfg_pin(GPIO_A06, S5P_GPIO_FUNC(0x3));
- gpio_cfg_pin(GPIO_A07, S5P_GPIO_FUNC(0x3));
+ suffix = 2;
break;
case PERIPH_ID_I2C3:
- gpio_cfg_pin(GPIO_A12, S5P_GPIO_FUNC(0x3));
- gpio_cfg_pin(GPIO_A13, S5P_GPIO_FUNC(0x3));
+ suffix = 3;
break;
case PERIPH_ID_I2C4:
- gpio_cfg_pin(GPIO_A20, S5P_GPIO_FUNC(0x3));
- gpio_cfg_pin(GPIO_A21, S5P_GPIO_FUNC(0x3));
+ suffix = 4;
break;
case PERIPH_ID_I2C5:
- gpio_cfg_pin(GPIO_A22, S5P_GPIO_FUNC(0x3));
- gpio_cfg_pin(GPIO_A23, S5P_GPIO_FUNC(0x3));
+ suffix = 5;
break;
case PERIPH_ID_I2C6:
- gpio_cfg_pin(GPIO_B13, S5P_GPIO_FUNC(0x4));
- gpio_cfg_pin(GPIO_B14, S5P_GPIO_FUNC(0x4));
+ suffix = 6;
break;
case PERIPH_ID_I2C7:
- gpio_cfg_pin(GPIO_B22, S5P_GPIO_FUNC(0x3));
- gpio_cfg_pin(GPIO_B23, S5P_GPIO_FUNC(0x3));
+ suffix = 7;
break;
}
+
+ pnode = fdtdec_next_alias(gd->fdt_blob, "i2c",
+ COMPAT_SAMSUNG_S3C2440_I2C, &suffix);
+
+ return pinmux_group_set(&pingrp, pnode);
}
-static void exynos5_i2s_config(int peripheral)
+static int exynos5_i2s_config(int peripheral)
{
- int i;
+ int suffix, pnode;
+ struct pin_group pingrp;
+
+ if (peripheral == PERIPH_ID_I2S1) {
+ suffix = 1;
+ pnode = fdtdec_next_alias(gd->fdt_blob, "i2s",
+ COMPAT_SAMSUNG_EXYNOS_I2S, &suffix);
+ }
- for (i = 0; i < 5; i++)
- gpio_cfg_pin(GPIO_B00+i, S5P_GPIO_FUNC(0x02));
+ return pinmux_group_set(&pingrp, pnode);
}
-void exynos5_spi_config(int peripheral)
+int exynos5_spi_config(int peripheral)
{
- int cfg = 0, pin = 0, i;
+ int suffix, pnode;
+ static struct pin_group pingrp;
switch (peripheral) {
case PERIPH_ID_SPI0:
- cfg = S5P_GPIO_FUNC(0x2);
- pin = GPIO_A20;
+ suffix = 0;
break;
case PERIPH_ID_SPI1:
- cfg = S5P_GPIO_FUNC(0x2);
- pin = GPIO_A24;
+ suffix = 1;
break;
case PERIPH_ID_SPI2:
- cfg = S5P_GPIO_FUNC(0x5);
- pin = GPIO_B11;
+ suffix = 2;
break;
case PERIPH_ID_SPI3:
- cfg = S5P_GPIO_FUNC(0x2);
- pin = GPIO_F10;
+ suffix = 3;
break;
case PERIPH_ID_SPI4:
- for (i = 0; i < 2; i++) {
- gpio_cfg_pin(GPIO_F02 + i, S5P_GPIO_FUNC(0x4));
- gpio_cfg_pin(GPIO_E04 + i, S5P_GPIO_FUNC(0x4));
- }
+ suffix = 4;
break;
}
- if (peripheral != PERIPH_ID_SPI4) {
- for (i = pin; i < pin + 4; i++)
- gpio_cfg_pin(i, cfg);
- }
+
+ pnode = fdtdec_next_alias(gd->fdt_blob, "spi",
+ COMPAT_SAMSUNG_EXYNOS_SPI, &suffix);
+
+ return pinmux_group_set(&pingrp, pnode);
}
-static int exynos5_pinmux_config(int peripheral, int flags)
+static int exynos5_pinmux_config(int peripheral)
{
switch (peripheral) {
case PERIPH_ID_UART0:
case PERIPH_ID_UART1:
case PERIPH_ID_UART2:
case PERIPH_ID_UART3:
- exynos5_uart_config(peripheral);
+ return exynos5_uart_config(peripheral);
break;
case PERIPH_ID_SDMMC0:
case PERIPH_ID_SDMMC1:
case PERIPH_ID_SDMMC2:
case PERIPH_ID_SDMMC3:
- return exynos5_mmc_config(peripheral, flags);
+ return exynos5_mmc_config(peripheral);
+ break;
case PERIPH_ID_SROMC:
- exynos5_sromc_config(flags);
+ return exynos5_sromc_config();
break;
case PERIPH_ID_I2C0:
case PERIPH_ID_I2C1:
@@ -297,24 +326,22 @@ static int exynos5_pinmux_config(int peripheral, int flags)
case PERIPH_ID_I2C5:
case PERIPH_ID_I2C6:
case PERIPH_ID_I2C7:
- exynos5_i2c_config(peripheral, flags);
+ return exynos5_i2c_config(peripheral);
break;
case PERIPH_ID_I2S1:
- exynos5_i2s_config(peripheral);
+ return exynos5_i2s_config(peripheral);
break;
case PERIPH_ID_SPI0:
case PERIPH_ID_SPI1:
case PERIPH_ID_SPI2:
case PERIPH_ID_SPI3:
case PERIPH_ID_SPI4:
- exynos5_spi_config(peripheral);
+ return exynos5_spi_config(peripheral);
break;
default:
debug("%s: invalid peripheral %d", __func__, peripheral);
return -1;
}
-
- return 0;
}
static void exynos4_i2c_config(int peripheral, int flags)
@@ -427,7 +454,7 @@ static int exynos4_pinmux_config(int peripheral, int flags)
int exynos_pinmux_config(int peripheral, int flags)
{
if (cpu_is_exynos5())
- return exynos5_pinmux_config(peripheral, flags);
+ return exynos5_pinmux_config(peripheral);
else if (cpu_is_exynos4())
return exynos4_pinmux_config(peripheral, flags);
else {
@@ -495,6 +522,6 @@ int name_to_gpio(const char *name)
if (i == ARRAY_SIZE(exynos5_gpio_table))
return -1;
-
+
return num;
}
diff --git a/arch/arm/dts/exynos5250-pinctrl.dtsi b/arch/arm/dts/exynos5250-pinctrl.dtsi
new file mode 100644
index 0000000..3f4dc59
--- /dev/null
+++ b/arch/arm/dts/exynos5250-pinctrl.dtsi
@@ -0,0 +1,675 @@
+/*
+ * Samsung's Exynos5250 SoC pin-mux and pin-config device tree source
+ *
+ * Copyright (c) 2013 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+ *
+ * Samsung's Exynos5250 SoC pin-mux and pin-config options are listed as device
+ * tree nodes in this file.
+ *
+ * Note: This file does not include pin-ctrl subnodes for all the controllers in
+ * Exynos5250 SoC. It can be updated as per need in future.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+/ {
+ pinctrl_0: pinctrl at 11400000 {
+ compatible = "samsung,pinctrl";
+ reg = <0x11400000 0x1000>;
+ interrupts = <0 46 0>;
+
+ gpa0: gpa0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpa1: gpa1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpa2: gpa2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpb0: gpb0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpb1: gpb1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpb2: gpb2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpb3: gpb3 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpc0: gpc0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpc1: gpc1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpc2: gpc2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpc3: gpc3 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpd0: gpd0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpd1: gpd1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpy0: gpy0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpy1: gpy1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpy2: gpy2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpy3: gpy3 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpy4: gpy4 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpy5: gpy5 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpy6: gpy6 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ gpc4: gpc4 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpx0: gpx0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpx1: gpx1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpx2: gpx2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpx3: gpx3 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ uart0_data: uart0-data {
+ samsung,pins = "gpa0-0", "gpa0-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart0_fctl: uart0-fctl {
+ samsung,pins = "gpa0-2", "gpa0-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samaung,pin-drv = <0>;
+ };
+
+ uart1_data: uart1-data {
+ samsung,pins = "gpd0-0", "gpd0-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart1_fctl: uart1-fctl {
+ samsung,pins = "gpd0-2", "gpd0-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samaung,pin-drv = <0>;
+ };
+
+ uart2_data: uart2-data {
+ samsung,pins = "gpa1-0", "gpa1-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart2_fctl: uart2-fctl {
+ samsung,pins = "gpa1-2", "gpa1-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samaung,pin-drv = <0>;
+ };
+
+ uart3_data: uart3-data {
+ samsung,pins = "gpa1-4", "gpa1-5";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ sd0_clk: sd0-clk {
+ samsung,pins = "gpc0-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_cmd: sd0-cmd {
+ samsung,pins = "gpc0-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_cd: sd0-cd {
+ samsung,pins = "gpc0-2";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_bus1: sd0-bus-width1 {
+ samsung,pins = "gpc0-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_bus4: sd0-bus-width4 {
+ samsung,pins = "gpc0-3", "gpc0-4", "gpc0-5", "gpc0-6";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd0_bus8: sd0-bus-width8 {
+ samsung,pins = "gpc1-0", "gpc1-1", "gpc1-2", "gpc1-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd1_clk: sd1-clk {
+ samsung,pins = "gpc2-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd1_cmd: sd1-cmd {
+ samsung,pins = "gpc2-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd1_cd: sd1-cd {
+ samsung,pins = "gpc2-2";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd1_bus1: sd1-bus-width1 {
+ samsung,pins = "gpc2-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd1_bus4: sd1-bus-width4 {
+ samsung,pins = "gpc2-3", "gpc2-4", "gpc2-5", "gpc2-6";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd2_clk: sd2-clk {
+ samsung,pins = "gpc3-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd2_cmd: sd2-cmd {
+ samsung,pins = "gpc3-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd2_cd: sd2-cd {
+ samsung,pins = "gpc3-2";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd2_bus1: sd2-bus-width1 {
+ samsung,pins = "gpc3-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd2_bus4: sd2-bus-width4 {
+ samsung,pins = "gpc3-3", "gpc3-4", "gpc3-5", "gpc3-6";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd2_bus8: sd2-bus-width8 {
+ samsung,pins = "gpc4-3", "gpc4-4", "gpc4-5", "gpc4-6";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd3_clk: sd3-clk {
+ samsung,pins = "gpc4-0";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd3_cmd: sd3-cmd {
+ samsung,pins = "gpc4-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd3_cd: sd3-cd {
+ samsung,pins = "gpc4-2";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd3_bus1: sd3-bus-width1 {
+ samsung,pins = "gpc4-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ sd3_bus4: sd3-bus-width4 {
+ samsung,pins = "gpc4-3", "gpc4-4", "gpc4-5", "gpc4-6";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <3>;
+ };
+
+ srom_cs1: srom-cs1 {
+ samsung,pins = "gpy0-1", "gpy0-4", "gpy0-5";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ srom_ebi: srom-ebi-enable {
+ samsung,pins = "gpy1-0", "gpy1-1", "gpy1-2", "gpy1-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ srom_ebi_a: srom-ebi-addr-lines {
+ samsung,pins = "gpy3-0", "gpy3-1", "gpy3-2", "gpy3-3",
+ "gpy3-4", "gpy3-5", "gpy3-6", "gpy3-7";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ srom_ebi_d: srom-ebi-data-lines {
+ samsung,pins = "gpy5-0", "gpy5-1", "gpy5-2", "gpy5-3",
+ "gpy5-4", "gpy5-5", "gpy5-6", "gpy5-7",
+ "gpy6-0", "gpy6-1", "gpy6-2", "gpy6-3",
+ "gpy6-4", "gpy6-5", "gpy6-6", "gpy6-7";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2s: i2s {
+ samsung,pins = "gpb0-0", "gpb0-1", "gpb0-2", "gpb0-3",
+ "gpb0-4";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ spi0_bus: spi0-bus {
+ samsung,pins = "gpa2-0", "gpa2-1", "gpa2-2", "gpa2-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ spi1_bus: spi1-bus {
+ samsung,pins = "gpa2-4", "gpa2-5", "gpa2-6", "gpa2-7";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ spi2_bus: spi2-bus {
+ samsung,pins = "gpb1-1", "gpb1-2", "gpb1-3", "gpb1-4";
+ samsung,pin-function = <5>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c0_bus: i2c0-bus {
+ samsung,pins = "gpb3-0", "gpb3-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c1_bus: i2c1-bus {
+ samsung,pins = "gpb3-2", "gpb3-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c2_bus: i2c2-bus {
+ samsung,pins = "gpa0-6", "gpa0-7";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samaung,pin-drv = <0>;
+ };
+
+ i2c3_bus: i2c3-bus {
+ samsung,pins = "gpa1-2", "gpa1-3";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samaung,pin-drv = <0>;
+ };
+
+ i2c4_bus: i2c4-bus {
+ samsung,pins = "gpa2-0", "gpa2-1";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samaung,pin-drv = <0>;
+ };
+
+ i2c5_bus: i2c5-bus {
+ samsung,pins = "gpa2-2", "gpa2-3";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samaung,pin-drv = <0>;
+ };
+
+ i2c6_bus: i2c6-bus {
+ samsung,pins = "gpb1-3", "gpb1-4";
+ samsung,pin-function = <4>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c7_bus: i2c7-bus {
+ samsung,pins = "gpb2-2", "gpb2-3";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+ };
+
+ pinctrl_1: pinctrl at 13400000 {
+ compatible = "samsung,pinctrl";
+ reg = <0x13400000 0x1000>;
+ interrupts = <0 45 0>;
+
+ gpe0: gpe0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpe1: gpe1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpf0: gpf0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpf1: gpf1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpg0: gpg0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpg1: gpg1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpg2: gpg2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gph0: gph0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gph1: gph1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ spi3_bus: spi3-bus {
+ samsung,pins = "gpf1-0", "gpf1-1", "gpf1-2", "gpf1-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+
+ spi4_bus: spi4-bus {
+ samsung,pins = "gpf0-2", "gpf0-3", "gpe0-4", "gpe0-5";
+ samsung,pin-function = <4>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+ };
+
+ pinctrl_2: pinctrl at 10d10000 {
+ compatible = "samsung,pinctrl-exynos5250";
+ reg = <0x10d10000 0x1000>;
+ interrupts = <0 45 0>;
+
+ gpv0: gpv0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpv1: gpv1 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpv2: gpv2 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpv3: gpv3 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpv4: gpv4 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+ };
+
+ pinctrl_3: pinctrl at 03680000 {
+ compatible = "samsung,pinctrl-exynos5250";
+ reg = <0x03680000 0x1000>;
+ interrupts = <0 45 0>;
+
+ gpz: gpz {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+ };
+};
diff --git a/arch/arm/dts/exynos5250.dtsi b/arch/arm/dts/exynos5250.dtsi
index ed8c8dd..cbe31a1 100644
--- a/arch/arm/dts/exynos5250.dtsi
+++ b/arch/arm/dts/exynos5250.dtsi
@@ -18,6 +18,7 @@
*/
/include/ "skeleton.dtsi"
+/include/ "exynos5250-pinctrl.dtsi"
/ {
compatible = "samsung,exynos5250";
@@ -27,6 +28,10 @@
reg = <0x12250000 0x20>;
#address-cells = <1>;
#size-cells = <0>;
+ samsung,pinctrl-names = "srom-cs1",
+ "srom-ebi-enable",
+ "srom-ebi-addr-lines",
+ "srom-ebi-data-lines";
};
i2c at 12c60000 {
@@ -35,6 +40,7 @@
compatible = "samsung,s3c2440-i2c";
reg = <0x12C60000 0x100>;
interrupts = <0 56 0>;
+ samsung,pinctrl-names = "i2c0-bus";
};
i2c at 12c70000 {
@@ -43,6 +49,7 @@
compatible = "samsung,s3c2440-i2c";
reg = <0x12C70000 0x100>;
interrupts = <0 57 0>;
+ samsung,pinctrl-names = "i2c1-bus";
};
i2c at 12c80000 {
@@ -51,6 +58,7 @@
compatible = "samsung,s3c2440-i2c";
reg = <0x12C80000 0x100>;
interrupts = <0 58 0>;
+ samsung,pinctrl-names = "i2c2-bus";
};
i2c at 12c90000 {
@@ -59,6 +67,7 @@
compatible = "samsung,s3c2440-i2c";
reg = <0x12C90000 0x100>;
interrupts = <0 59 0>;
+ samsung,pinctrl-names = "i2c3-bus";
};
i2c at 12ca0000 {
@@ -67,6 +76,7 @@
compatible = "samsung,s3c2440-i2c";
reg = <0x12CA0000 0x100>;
interrupts = <0 60 0>;
+ samsung,pinctrl-names = "i2c4-bus";
};
i2c at 12cb0000 {
@@ -75,6 +85,7 @@
compatible = "samsung,s3c2440-i2c";
reg = <0x12CB0000 0x100>;
interrupts = <0 61 0>;
+ samsung,pinctrl-names = "i2c5-bus";
};
i2c at 12cc0000 {
@@ -83,6 +94,7 @@
compatible = "samsung,s3c2440-i2c";
reg = <0x12CC0000 0x100>;
interrupts = <0 62 0>;
+ samsung,pinctrl-names = "i2c6-bus";
};
i2c at 12cd0000 {
@@ -91,6 +103,7 @@
compatible = "samsung,s3c2440-i2c";
reg = <0x12CD0000 0x100>;
interrupts = <0 63 0>;
+ samsung,pinctrl-names = "i2c7-bus";
};
sound at 12d60000 {
@@ -104,6 +117,7 @@
compatible = "samsung,exynos-spi";
reg = <0x12d20000 0x30>;
interrupts = <0 68 0>;
+ samsung,pinctrl-names = "spi0-bus";
};
spi at 12d30000 {
@@ -112,6 +126,7 @@
compatible = "samsung,exynos-spi";
reg = <0x12d30000 0x30>;
interrupts = <0 69 0>;
+ samsung,pinctrl-names = "spi1-bus";
};
spi at 12d40000 {
@@ -121,6 +136,7 @@
reg = <0x12d40000 0x30>;
clock-frequency = <50000000>;
interrupts = <0 70 0>;
+ samsung,pinctrl-names = "spi2-bus";
};
spi at 131a0000 {
@@ -129,6 +145,7 @@
compatible = "samsung,exynos-spi";
reg = <0x131a0000 0x30>;
interrupts = <0 129 0>;
+ samsung,pinctrl-names = "spi3-bus";
};
spi at 131b0000 {
@@ -137,6 +154,7 @@
compatible = "samsung,exynos-spi";
reg = <0x131b0000 0x30>;
interrupts = <0 130 0>;
+ samsung,pinctrl-names = "spi4-bus";
};
ehci at 12110000 {
@@ -151,4 +169,78 @@
};
};
+ serial at 12C00000 {
+ compatible = "samsung,exynos-uart";
+ reg = <0x12C00000 0x100>;
+ samsung,pinctrl-names = "uart0-data",
+ "uart0-fctl";
+ };
+
+ serial at 12C10000 {
+ compatible = "samsung,exynos-uart";
+ reg = <0x12C10000 0x100>;
+ samsung,pinctrl-names = "uart1-data",
+ "uart1-fctl";
+ };
+
+ serial at 12C20000 {
+ compatible = "samsung,exynos-uart";
+ reg = <0x12C20000 0x100>;
+ samsung,pinctrl-names = "uart2-data",
+ "uart2-fctl";
+ };
+
+ serial at 12C30000 {
+ compatible = "samsung,exynos-uart";
+ reg = <0x12C30000 0x100>;
+ samsung,pinctrl-names = "uart3-data";
+ };
+
+ dwmmc at 12200000 {
+ compatible = "samsung,exynos-mshc";
+ reg = <0x12200000 0x1000>;
+ samsung,pinctrl-names = "sd0-clk", "sd0-cmd",
+ "sd0-bus-width4",
+ "sd0-bus-width8";
+ };
+
+ dwmmc at 12210000 {
+ compatible = "samsung,exynos-mshc";
+ reg = <0x12210000 0x1000>;
+ samsung,pinctrl-names = "sd1-clk", "sd1-cmd",
+ "sd1-bus-width4";
+ };
+
+ dwmmc at 12220000 {
+ compatible = "samsung,exynos-mshc";
+ reg = <0x12220000 0x1000>;
+ samsung,pinctrl-names = "sd2-clk", "sd2-cmd",
+ "sd2-bus-width4",
+ "sd2-bus-width8";
+ };
+
+ dwmmc at 12230000 {
+ compatible = "samsung,exynos-mshc";
+ reg = <0x12230000 0x1000>;
+ samsung,pinctrl-names = "sd3-clk", "sd3-cmd",
+ "sd3-bus-width4";
+ };
+
+ i2s at 03830000 {
+ compatible = "samsung,exynos-i2s";
+ reg = <0x03830000 0x100>;
+ samsung,pinctrl-names = "i2s0";
+ };
+
+ i2s at 12d60000 {
+ compatible = "samsung,exynos-i2s";
+ reg = <0x12d60000 0x100>;
+ samsung,pinctrl-names = "i2s1";
+ };
+
+ i2s at 12D70000 {
+ compatible = "samsung,exynos-i2s";
+ reg = <0x12D70000 0x100>;
+ samsung,pinctrl-names = "i2s2";
+ };
};
diff --git a/board/samsung/dts/exynos5250-smdk5250.dts b/board/samsung/dts/exynos5250-smdk5250.dts
index cbfab6f..30ba5aa 100644
--- a/board/samsung/dts/exynos5250-smdk5250.dts
+++ b/board/samsung/dts/exynos5250-smdk5250.dts
@@ -30,6 +30,17 @@
spi2 = "/spi at 12d40000";
spi3 = "/spi at 131a0000";
spi4 = "/spi at 131b0000";
+ mshc0 = "/dwmmc at 12200000";
+ mshc1 = "/dwmmc at 12210000";
+ mshc2 = "/dwmmc at 12220000";
+ mshc3 = "/dwmmc at 12230000";
+ uart0 = "/serial at 12C00000";
+ uart1 = "/serial at 12C10000";
+ uart2 = "/serial at 12C20000";
+ uart3 = "/serial at 12C30000";
+ i2s0 = "/i2s at 03830000";
+ i2s1 = "/sound at 12d60000";
+ i2s2 = "/i2s at 12D70000";
};
sromc at 12250000 {
diff --git a/doc/device-tree-bindings/samsung-pinctrl.txt b/doc/device-tree-bindings/samsung-pinctrl.txt
new file mode 100644
index 0000000..708ca45
--- /dev/null
+++ b/doc/device-tree-bindings/samsung-pinctrl.txt
@@ -0,0 +1,253 @@
+Samsung GPIO and Pin Mux/Config controller
+
+Samsung's ARM based SoC's integrates a GPIO and Pin mux/config hardware
+controller. It controls the input/output settings on the available pads/pins
+and also provides ability to multiplex and configure the output of various
+on-chip controllers onto these pads.
+
+Required Properties:
+- compatible: should be one of the following.
+ - "samsung,pinctrl": for Exynos compatible pin-controller.
+
+- reg: Base address of the pin controller hardware module and length of
+ the address space it occupies.
+
+- Pin banks as child nodes: Pin banks of the controller are represented by child
+ nodes of the controller node. Bank name is taken from name of the node. Each
+ bank node must contain following properties:
+
+ - gpio-controller: identifies the node as a gpio controller and pin bank.
+ - #gpio-cells: number of cells in GPIO specifier. Since the generic GPIO
+ binding is used, the amount of cells must be specified as 2. See generic
+ GPIO binding documentation for description of particular cells.
+
+- Pin mux/config groups as child nodes: The pin mux (selecting pin function
+ mode) and pin config (pull up/down, driver strength) settings are represented
+ as child nodes of the pin-controller node. There should be atleast one
+ child node and there is no limit on the count of these child nodes.
+
+ The child node should contain a list of pin(s) on which a particular pin
+ function selection or pin configuration (or both) have to applied. This
+ list of pins is specified using the property name "samsung,pins". There
+ should be atleast one pin specfied for this property and there is no upper
+ limit on the count of pins that can be specified. The pins are specified
+ using pin names which are derived from the hardware manual of the SoC. As
+ an example, the pins in GPA0 bank of the pin controller can be represented
+ as "gpa0-0", "gpa0-1", "gpa0-2" and so on. The names should be in lower case.
+ The format of the pin names should be (as per the hardware manual)
+ "[pin bank name]-[pin number within the bank]".
+
+ The pin function selection that should be applied on the pins listed in the
+ child node is specified using the "samsung,pin-function" property. The value
+ of this property that should be applied to each of the pins listed in the
+ "samsung,pins" property should be picked from the hardware manual of the SoC
+ for the specified pin group. This property is optional in the child node if
+ no specific function selection is desired for the pins listed in the child
+ node. The value of this property is used as-is to program the pin-controller
+ function selector register of the pin-bank.
+
+ The child node can also optionally specify one or more of the pin
+ configuration that should be applied on all the pins listed in the
+ "samsung,pins" property of the child node. The following pin configuration
+ properties are supported.
+
+ - samsung,pin-pud: Pull up/down configuration.
+ - samsung,pin-drv: Drive strength configuration.
+ - samsung,pin-pud-pdn: Pull up/down configuration in power down mode.
+ - samsung,pin-drv-pdn: Drive strength configuration in power down mode.
+
+ The values specified by these config properties should be derived from the
+ hardware manual and these values are programmed as-is into the pin
+ pull up/down and driver strength register of the pin-controller.
+
+ Note: A child should include atleast a pin function selection property or
+ pin configuration property (one or more) or both.
+
+ The client nodes that require a particular pin function selection and/or
+ pin configuration should use the bindings listed in the "pinctrl-bindings.txt"
+ file.
+
+External GPIO and Wakeup Interrupts:
+
+The controller supports two types of external interrupts over gpio. The first
+is the external gpio interrupt and second is the external wakeup interrupts.
+The difference between the two is that the external wakeup interrupts can be
+used as system wakeup events.
+
+A. External GPIO Interrupts: For supporting external gpio interrupts, the
+ following properties should be specified in the pin-controller device node.
+
+ - interrupt-parent: phandle of the interrupt parent to which the external
+ GPIO interrupts are forwarded to.
+ - interrupts: interrupt specifier for the controller. The format and value of
+ the interrupt specifier depends on the interrupt parent for the controller.
+
+ In addition, following properties must be present in node of every bank
+ of pins supporting GPIO interrupts:
+
+ - interrupt-controller: identifies the controller node as interrupt-parent.
+ - #interrupt-cells: the value of this property should be 2.
+ - First Cell: represents the external gpio interrupt number local to the
+ external gpio interrupt space of the controller.
+ - Second Cell: flags to identify the type of the interrupt
+ - 1 = rising edge triggered
+ - 2 = falling edge triggered
+ - 3 = rising and falling edge triggered
+ - 4 = high level triggered
+ - 8 = low level triggered
+
+B. External Wakeup Interrupts: For supporting external wakeup interrupts, a
+ child node representing the external wakeup interrupt controller should be
+ included in the pin-controller device node. This child node should include
+ the following properties.
+
+ - compatible: identifies the type of the external wakeup interrupt controller
+ The possible values are:
+ - samsung,wakeup-eint: represents wakeup interrupt controller
+ found on Samsung Exynos SoC.
+ - interrupt-parent: phandle of the interrupt parent to which the external
+ wakeup interrupts are forwarded to.
+ - interrupts: interrupt used by multiplexed wakeup interrupts.
+
+ In addition, following properties must be present in node of every bank
+ of pins supporting wake-up interrupts:
+
+ - interrupt-controller: identifies the node as interrupt-parent.
+ - #interrupt-cells: the value of this property should be 2
+ - First Cell: represents the external wakeup interrupt number local to
+ the external wakeup interrupt space of the controller.
+ - Second Cell: flags to identify the type of the interrupt
+ - 1 = rising edge triggered
+ - 2 = falling edge triggered
+ - 3 = rising and falling edge triggered
+ - 4 = high level triggered
+ - 8 = low level triggered
+
+ Node of every bank of pins supporting direct wake-up interrupts (without
+ multiplexing) must contain following properties:
+
+ - interrupt-parent: phandle of the interrupt parent to which the external
+ wakeup interrupts are forwarded to.
+ - interrupts: interrupts of the interrupt parent which are used for external
+ wakeup interrupts from pins of the bank, must contain interrupts for all
+ pins of the bank.
+
+Aliases:
+
+All the pin controller nodes should be represented in the aliases node using
+the following format 'pinctrl{n}' where n is a unique number for the alias.
+
+Example: A pin-controller node with pin banks:
+
+ pinctrl_0: pinctrl at 11400000 {
+ compatible = "samsung,pinctrl;
+ reg = <0x11400000 0x1000>;
+ interrupts = <0 47 0>;
+
+ /* ... */
+
+ /* Pin bank without external interrupts */
+ gpy0: gpy0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+ };
+
+ /* ... */
+
+ /* Pin bank with external GPIO or muxed wake-up interrupts */
+ gpj0: gpj0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ /* ... */
+
+ /* Pin bank with external direct wake-up interrupts */
+ gpx0: gpx0 {
+ gpio-controller;
+ #gpio-cells = <2>;
+
+ interrupt-controller;
+ interrupt-parent = <&gic>;
+ interrupts = <0 16 0>, <0 17 0>, <0 18 0>, <0 19 0>,
+ <0 20 0>, <0 21 0>, <0 22 0>, <0 23 0>;
+ #interrupt-cells = <2>;
+ };
+
+ /* ... */
+ };
+
+Example 1: A pin-controller node with pin groups.
+
+ pinctrl_0: pinctrl at 11400000 {
+ compatible = "samsung,pinctrl";
+ reg = <0x11400000 0x1000>;
+ interrupts = <0 47 0>;
+
+ /* ... */
+
+ uart0_data: uart0-data {
+ samsung,pins = "gpa0-0", "gpa0-1";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart0_fctl: uart0-fctl {
+ samsung,pins = "gpa0-2", "gpa0-3";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart1_data: uart1-data {
+ samsung,pins = "gpa0-4", "gpa0-5";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ uart1_fctl: uart1-fctl {
+ samsung,pins = "gpa0-6", "gpa0-7";
+ samsung,pin-function = <2>;
+ samsung,pin-pud = <0>;
+ samsung,pin-drv = <0>;
+ };
+
+ i2c2_bus: i2c2-bus {
+ samsung,pins = "gpa0-6", "gpa0-7";
+ samsung,pin-function = <3>;
+ samsung,pin-pud = <3>;
+ samsung,pin-drv = <0>;
+ };
+ };
+
+Example 2: A pin-controller node with external wakeup interrupt controller node.
+
+ pinctrl_1: pinctrl at 11000000 {
+ compatible = "samsung,pinctrl";
+ reg = <0x11000000 0x1000>;
+ interrupts = <0 46 0>
+
+ /* ... */
+
+ wakeup-interrupt-controller {
+ compatible = "samsung,wakeup-eint";
+ interrupt-parent = <&gic>;
+ interrupts = <0 32 0>;
+ };
+ };
+
+Example 3: A uart client node that supports 'default' and 'flow-control' states.
+
+ uart at 13800000 {
+ compatible = "samsung,uart";
+ reg = <0x13800000 0x100>;
+ interrupts = <0 52 0>;
+ pinctrl-names = "default", "flow-control;
+ pinctrl-0 = <&uart0_data>;
+ pinctrl-1 = <&uart0_data &uart0_fctl>;
+ };
diff --git a/include/fdtdec.h b/include/fdtdec.h
index 77f244f..26692e5 100644
--- a/include/fdtdec.h
+++ b/include/fdtdec.h
@@ -81,6 +81,10 @@ enum fdt_compat_id {
COMPAT_SAMSUNG_EXYNOS_EHCI, /* Exynos EHCI controller */
COMPAT_SAMSUNG_EXYNOS_USB_PHY, /* Exynos phy controller for usb2.0 */
COMPAT_MAXIM_MAX77686_PMIC, /* MAX77686 PMIC */
+ COMPAT_SAMSUNG_EXYNOS_UART, /* Exynos serial */
+ COMPAT_SAMSUNG_EXYNOS_MSHC, /* Exynos MMC controller */
+ COMPAT_SAMSUNG_EXYNOS_I2S, /* Exynos MMC controller */
+ COMPAT_SAMSUNG_PINCTRL, /* PINCTRL */
COMPAT_COUNT,
};
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index 3ae348d..88dd669 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -56,6 +56,10 @@ static const char * const compat_names[COMPAT_COUNT] = {
COMPAT(SAMSUNG_EXYNOS_EHCI, "samsung,exynos-ehci"),
COMPAT(SAMSUNG_EXYNOS_USB_PHY, "samsung,exynos-usb-phy"),
COMPAT(MAXIM_MAX77686_PMIC, "maxim,max77686_pmic"),
+ COMPAT(SAMSUNG_EXYNOS_UART, "samsung,exynos-uart"),
+ COMPAT(SAMSUNG_EXYNOS_MSHC, "samsung,exynos-mshc"),
+ COMPAT(SAMSUNG_EXYNOS_I2S, "samsung,exynos-i2s"),
+ COMPAT(SAMSUNG_PINCTRL, "samsung,pinctrl"),
};
const char *fdtdec_get_compatible(enum fdt_compat_id id)
--
1.8.0
More information about the U-Boot
mailing list