summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/include/asm/arch-aspeed/pinctrl.h52
-rw-r--r--arch/arm/include/asm/arch-aspeed/scu_ast2500.h19
-rw-r--r--drivers/pinctrl/Kconfig9
-rw-r--r--drivers/pinctrl/Makefile1
-rw-r--r--drivers/pinctrl/aspeed/Makefile1
-rw-r--r--drivers/pinctrl/aspeed/pinctrl_ast2500.c127
6 files changed, 209 insertions, 0 deletions
diff --git a/arch/arm/include/asm/arch-aspeed/pinctrl.h b/arch/arm/include/asm/arch-aspeed/pinctrl.h
new file mode 100644
index 0000000..365dc21
--- /dev/null
+++ b/arch/arm/include/asm/arch-aspeed/pinctrl.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2017 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#ifndef _ASM_ARCH_PERIPH_H
+#define _ASM_ARCH_PERIPH_H
+
+/*
+ * Peripherals supported by the hardware.
+ * These are used to specify pinctrl settings.
+ */
+
+enum periph_id {
+ PERIPH_ID_UART1,
+ PERIPH_ID_UART2,
+ PERIPH_ID_UART3,
+ PERIPH_ID_UART4,
+ PERIPH_ID_LPC,
+ PERIPH_ID_PWM0,
+ PERIPH_ID_PWM1,
+ PERIPH_ID_PWM2,
+ PERIPH_ID_PWM3,
+ PERIPH_ID_PWM4,
+ PERIPH_ID_PWM5,
+ PERIPH_ID_PWM6,
+ PERIPH_ID_PWM7,
+ PERIPH_ID_PWM8,
+ PERIPH_ID_MAC1,
+ PERIPH_ID_MAC2,
+ PERIPH_ID_VIDEO,
+ PERIPH_ID_SPI1,
+ PERIPH_ID_SPI2,
+ PERIPH_ID_I2C1,
+ PERIPH_ID_I2C2,
+ PERIPH_ID_I2C3,
+ PERIPH_ID_I2C4,
+ PERIPH_ID_I2C5,
+ PERIPH_ID_I2C6,
+ PERIPH_ID_I2C7,
+ PERIPH_ID_I2C8,
+ PERIPH_ID_I2C9,
+ PERIPH_ID_I2C10,
+ PERIPH_ID_I2C11,
+ PERIPH_ID_I2C12,
+ PERIPH_ID_I2C13,
+ PERIPH_ID_I2C14,
+ PERIPH_ID_SD1,
+ PERIPH_ID_SD2,
+};
+
+#endif /* _ASM_ARCH_SCU_AST2500_H */
diff --git a/arch/arm/include/asm/arch-aspeed/scu_ast2500.h b/arch/arm/include/asm/arch-aspeed/scu_ast2500.h
index e2556f9..1cdd3b9 100644
--- a/arch/arm/include/asm/arch-aspeed/scu_ast2500.h
+++ b/arch/arm/include/asm/arch-aspeed/scu_ast2500.h
@@ -10,6 +10,8 @@
#define SCU_HWSTRAP_VGAMEM_MASK 3
#define SCU_HWSTRAP_VGAMEM_SHIFT 2
+#define SCU_HWSTRAP_MAC1_RGMII (1 << 6)
+#define SCU_HWSTRAP_MAC2_RGMII (1 << 7)
#define SCU_HWSTRAP_DDR4 (1 << 24)
#define SCU_HWSTRAP_CLKIN_25MHZ (1 << 23)
@@ -59,6 +61,23 @@
#define SCU_SYSRESET_AHB (1 << 1)
#define SCU_SYSRESET_SDRAM_WDT (1 << 0)
+/* Bits 16-27 in the register control pin functions for I2C devices 3-14 */
+#define SCU_PINMUX_CTRL5_I2C (1 << 16)
+
+/*
+ * The values are grouped by function, not by register.
+ * They are actually scattered across multiple loosely related registers.
+ */
+#define SCU_PIN_FUN_MAC1_MDC (1 << 30)
+#define SCU_PIN_FUN_MAC1_MDIO (1 << 31)
+#define SCU_PIN_FUN_MAC1_PHY_LINK (1 << 0)
+#define SCU_PIN_FUN_MAC2_MDIO (1 << 2)
+#define SCU_PIN_FUN_MAC2_PHY_LINK (1 << 1)
+#define SCU_PIN_FUN_SCL1 (1 << 12)
+#define SCU_PIN_FUN_SCL2 (1 << 14)
+#define SCU_PIN_FUN_SDA1 (1 << 13)
+#define SCU_PIN_FUN_SDA2 (1 << 15)
+
#ifndef __ASSEMBLY__
struct ast2500_clk_priv {
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 9cea6f2..f6616c5 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -248,6 +248,15 @@ config PINCTRL_STM32
the GPIO definitions and pin control functions for each available
multiplex function.
+config ASPEED_AST2500_PINCTRL
+ bool "Aspeed AST2500 pin control driver"
+ depends on DM && PINCTRL_GENERIC && ASPEED_AST2500
+ default y
+ help
+ Support pin multiplexing control on Aspeed ast2500 SoC. The driver uses
+ Generic Pinctrl framework and is compatible with the Linux driver,
+ i.e. it uses the same device tree configuration.
+
endif
source "drivers/pinctrl/meson/Kconfig"
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index 17a7173..1e5c425 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_$(SPL_)PINCTRL_GENERIC) += pinctrl-generic.o
obj-$(CONFIG_PINCTRL_AT91) += pinctrl-at91.o
obj-$(CONFIG_PINCTRL_AT91PIO4) += pinctrl-at91-pio4.o
obj-y += nxp/
+obj-$(CONFIG_ARCH_ASPEED) += aspeed/
obj-$(CONFIG_ARCH_ATH79) += ath79/
obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/
obj-$(CONFIG_PINCTRL_SANDBOX) += pinctrl-sandbox.o
diff --git a/drivers/pinctrl/aspeed/Makefile b/drivers/pinctrl/aspeed/Makefile
new file mode 100644
index 0000000..2e6ed60
--- /dev/null
+++ b/drivers/pinctrl/aspeed/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_ASPEED_AST2500_PINCTRL) += pinctrl_ast2500.o
diff --git a/drivers/pinctrl/aspeed/pinctrl_ast2500.c b/drivers/pinctrl/aspeed/pinctrl_ast2500.c
new file mode 100644
index 0000000..01f97c1
--- /dev/null
+++ b/drivers/pinctrl/aspeed/pinctrl_ast2500.c
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2017 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <asm/io.h>
+#include <asm/arch/pinctrl.h>
+#include <asm/arch/scu_ast2500.h>
+#include <dm/pinctrl.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * This driver works with very simple configuration that has the same name
+ * for group and function. This way it is compatible with the Linux Kernel
+ * driver.
+ */
+
+struct ast2500_pinctrl_priv {
+ struct ast2500_scu *scu;
+};
+
+static int ast2500_pinctrl_probe(struct udevice *dev)
+{
+ struct ast2500_pinctrl_priv *priv = dev_get_priv(dev);
+
+ priv->scu = ast_get_scu();
+
+ return 0;
+}
+
+struct ast2500_group_config {
+ char *group_name;
+ /* Control register number (1-10) */
+ unsigned reg_num;
+ /* The mask of control bits in the register */
+ u32 ctrl_bit_mask;
+};
+
+static const struct ast2500_group_config ast2500_groups[] = {
+ { "I2C1", 8, (1 << 13) | (1 << 12) },
+ { "I2C2", 8, (1 << 15) | (1 << 14) },
+ { "I2C3", 8, (1 << 16) },
+ { "I2C4", 5, (1 << 17) },
+ { "I2C4", 5, (1 << 17) },
+ { "I2C5", 5, (1 << 18) },
+ { "I2C6", 5, (1 << 19) },
+ { "I2C7", 5, (1 << 20) },
+ { "I2C8", 5, (1 << 21) },
+ { "I2C9", 5, (1 << 22) },
+ { "I2C10", 5, (1 << 23) },
+ { "I2C11", 5, (1 << 24) },
+ { "I2C12", 5, (1 << 25) },
+ { "I2C13", 5, (1 << 26) },
+ { "I2C14", 5, (1 << 27) },
+ { "MAC1LINK", 1, (1 << 0) },
+ { "MDIO1", 3, (1 << 31) | (1 << 30) },
+ { "MAC2LINK", 1, (1 << 1) },
+ { "MDIO2", 5, (1 << 2) },
+};
+
+static int ast2500_pinctrl_get_groups_count(struct udevice *dev)
+{
+ debug("PINCTRL: get_(functions/groups)_count\n");
+
+ return ARRAY_SIZE(ast2500_groups);
+}
+
+static const char *ast2500_pinctrl_get_group_name(struct udevice *dev,
+ unsigned selector)
+{
+ debug("PINCTRL: get_(function/group)_name %u\n", selector);
+
+ return ast2500_groups[selector].group_name;
+}
+
+static int ast2500_pinctrl_group_set(struct udevice *dev, unsigned selector,
+ unsigned func_selector)
+{
+ struct ast2500_pinctrl_priv *priv = dev_get_priv(dev);
+ const struct ast2500_group_config *config;
+ u32 *ctrl_reg;
+
+ debug("PINCTRL: group_set <%u, %u>\n", selector, func_selector);
+ if (selector >= ARRAY_SIZE(ast2500_groups))
+ return -EINVAL;
+
+ config = &ast2500_groups[selector];
+ if (config->reg_num > 6)
+ ctrl_reg = &priv->scu->pinmux_ctrl1[config->reg_num - 7];
+ else
+ ctrl_reg = &priv->scu->pinmux_ctrl[config->reg_num - 1];
+
+ ast_scu_unlock(priv->scu);
+ setbits_le32(ctrl_reg, config->ctrl_bit_mask);
+ ast_scu_lock(priv->scu);
+
+ return 0;
+}
+
+static struct pinctrl_ops ast2500_pinctrl_ops = {
+ .set_state = pinctrl_generic_set_state,
+ .get_groups_count = ast2500_pinctrl_get_groups_count,
+ .get_group_name = ast2500_pinctrl_get_group_name,
+ .get_functions_count = ast2500_pinctrl_get_groups_count,
+ .get_function_name = ast2500_pinctrl_get_group_name,
+ .pinmux_group_set = ast2500_pinctrl_group_set,
+};
+
+static const struct udevice_id ast2500_pinctrl_ids[] = {
+ { .compatible = "aspeed,ast2500-pinctrl" },
+ { .compatible = "aspeed,g5-pinctrl" },
+ { }
+};
+
+U_BOOT_DRIVER(pinctrl_ast2500) = {
+ .name = "aspeed_ast2500_pinctrl",
+ .id = UCLASS_PINCTRL,
+ .of_match = ast2500_pinctrl_ids,
+ .priv_auto_alloc_size = sizeof(struct ast2500_pinctrl_priv),
+ .ops = &ast2500_pinctrl_ops,
+ .probe = ast2500_pinctrl_probe,
+};