[U-Boot] [PATCH 1/2] pinctrl: uniphier: support pin configuration

Support the following DT properties: "bias-disable" "bias-pull-up" "bias-pull-down" "bias-pull-pin-default" "input-enable" "input-disable"
My main motivation is to support pull up/down biasing. For Pro5 and later SoCs, the pupdctrl register number is the same as the pinmux number, so this feature can be supported without having big pin tables.
Signed-off-by: Masahiro Yamada yamada.masahiro@socionext.com ---
drivers/pinctrl/uniphier/pinctrl-uniphier-core.c | 134 +++++++++++++++++++++-- drivers/pinctrl/uniphier/pinctrl-uniphier-ld11.c | 3 +- drivers/pinctrl/uniphier/pinctrl-uniphier-ld20.c | 3 +- drivers/pinctrl/uniphier/pinctrl-uniphier-ld6b.c | 1 + drivers/pinctrl/uniphier/pinctrl-uniphier-pro5.c | 3 +- drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c | 1 + drivers/pinctrl/uniphier/pinctrl-uniphier.h | 1 + 7 files changed, 134 insertions(+), 12 deletions(-)
diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-core.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-core.c index 51144b8..d8e9948 100644 --- a/drivers/pinctrl/uniphier/pinctrl-uniphier-core.c +++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-core.c @@ -5,6 +5,7 @@ * SPDX-License-Identifier: GPL-2.0+ */
+#include <common.h> #include <linux/io.h> #include <linux/err.h> #include <linux/sizes.h> @@ -15,6 +16,7 @@
#define UNIPHIER_PINCTRL_PINMUX_BASE 0x1000 #define UNIPHIER_PINCTRL_LOAD_PINMUX 0x1700 +#define UNIPHIER_PINCTRL_PUPDCTRL_BASE 0x1a00 #define UNIPHIER_PINCTRL_IECTRL 0x1d00
static const char *uniphier_pinctrl_dummy_name = "_dummy"; @@ -55,8 +57,8 @@ static const char *uniphier_pinmux_get_function_name(struct udevice *dev, return priv->socdata->functions[selector]; }
-static void uniphier_pinconf_input_enable_perpin(struct udevice *dev, - unsigned pin) +static int uniphier_pinconf_input_enable_perpin(struct udevice *dev, + unsigned int pin, int enable) { struct uniphier_pinctrl_priv *priv = dev_get_priv(dev); unsigned reg; @@ -66,18 +68,30 @@ static void uniphier_pinconf_input_enable_perpin(struct udevice *dev, mask = BIT(pin % 32);
tmp = readl(priv->base + reg); - tmp |= mask; + if (enable) + tmp |= mask; + else + tmp &= ~mask; writel(tmp, priv->base + reg); + + return 0; }
-static void uniphier_pinconf_input_enable_legacy(struct udevice *dev, - unsigned pin) +static int uniphier_pinconf_input_enable_legacy(struct udevice *dev, + unsigned int pin, int enable) { struct uniphier_pinctrl_priv *priv = dev_get_priv(dev); int pins_count = priv->socdata->pins_count; const struct uniphier_pinctrl_pin *pins = priv->socdata->pins; int i;
+ /* + * Multiple pins share one input enable, per-pin disabling is + * impossible. + */ + if (!enable) + return -EINVAL; + for (i = 0; i < pins_count; i++) { if (pins[i].number == pin) { unsigned int iectrl; @@ -89,18 +103,115 @@ static void uniphier_pinconf_input_enable_legacy(struct udevice *dev, writel(tmp, priv->base + UNIPHIER_PINCTRL_IECTRL); } } + + return 0; }
-static void uniphier_pinconf_input_enable(struct udevice *dev, unsigned pin) +static int uniphier_pinconf_input_enable(struct udevice *dev, + unsigned int pin, int enable) { struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
if (priv->socdata->caps & UNIPHIER_PINCTRL_CAPS_PERPIN_IECTRL) - uniphier_pinconf_input_enable_perpin(dev, pin); + return uniphier_pinconf_input_enable_perpin(dev, pin, enable); + else + return uniphier_pinconf_input_enable_legacy(dev, pin, enable); +} + +#if CONFIG_IS_ENABLED(PINCONF) + +static const struct pinconf_param uniphier_pinconf_params[] = { + { "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 }, + { "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 1 }, + { "bias-pull-down", PIN_CONFIG_BIAS_PULL_DOWN, 1 }, + { "bias-pull-pin-default", PIN_CONFIG_BIAS_PULL_PIN_DEFAULT, 1 }, + { "input-enable", PIN_CONFIG_INPUT_ENABLE, 1 }, + { "input-disable", PIN_CONFIG_INPUT_ENABLE, 0 }, +}; + +static int uniphier_pinconf_bias_set(struct udevice *dev, unsigned int pin, + unsigned int param, unsigned int arg) +{ + struct uniphier_pinctrl_priv *priv = dev_get_priv(dev); + unsigned int enable = 1; + unsigned int reg; + u32 mask, tmp; + + if (!(priv->socdata->caps & UNIPHIER_PINCTRL_CAPS_PUPD_SIMPLE)) + return -ENOTSUPP; + + switch (param) { + case PIN_CONFIG_BIAS_DISABLE: + enable = 0; + break; + case PIN_CONFIG_BIAS_PULL_UP: + case PIN_CONFIG_BIAS_PULL_DOWN: + if (arg == 0) /* total bias is not supported */ + return -EINVAL; + break; + case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT: + if (arg == 0) /* configuration ignored */ + return 0; + default: + BUG(); + } + + reg = UNIPHIER_PINCTRL_PUPDCTRL_BASE + pin / 32 * 4; + mask = BIT(pin % 32); + + tmp = readl(priv->base + reg); + if (enable) + tmp |= mask; else - uniphier_pinconf_input_enable_legacy(dev, pin); + tmp &= ~mask; + writel(tmp, priv->base + reg); + + return 0; +} + +static int uniphier_pinconf_set_one(struct udevice *dev, unsigned int pin, + unsigned int param, unsigned int arg) +{ + int ret; + + switch (param) { + case PIN_CONFIG_BIAS_DISABLE: + case PIN_CONFIG_BIAS_PULL_UP: + case PIN_CONFIG_BIAS_PULL_DOWN: + case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT: + ret = uniphier_pinconf_bias_set(dev, pin, param, arg); + break; + case PIN_CONFIG_INPUT_ENABLE: + ret = uniphier_pinconf_input_enable(dev, pin, arg); + break; + default: + printf("unsupported configuration parameter %u\n", param); + return -EINVAL; + } + + return ret; }
+static int uniphier_pinconf_group_set(struct udevice *dev, + unsigned int group_selector, + unsigned int param, unsigned int arg) +{ + struct uniphier_pinctrl_priv *priv = dev_get_priv(dev); + const struct uniphier_pinctrl_group *grp = + &priv->socdata->groups[group_selector]; + int i, ret; + + for (i = 0; i < grp->num_pins; i++) { + ret = uniphier_pinconf_set_one(dev, grp->pins[i], param, arg); + if (ret) + return ret; + } + + return 0; +} + +#endif /* CONFIG_IS_ENABLED(PINCONF) */ + static void uniphier_pinmux_set_one(struct udevice *dev, unsigned pin, int muxval) { @@ -112,7 +223,7 @@ static void uniphier_pinmux_set_one(struct udevice *dev, unsigned pin, u32 tmp;
/* some pins need input-enabling */ - uniphier_pinconf_input_enable(dev, pin); + uniphier_pinconf_input_enable(dev, pin, 1);
if (muxval < 0) return; /* dedicated pin; nothing to do for pin-mux */ @@ -174,6 +285,11 @@ const struct pinctrl_ops uniphier_pinctrl_ops = { .get_functions_count = uniphier_pinmux_get_functions_count, .get_function_name = uniphier_pinmux_get_function_name, .pinmux_group_set = uniphier_pinmux_group_set, +#if CONFIG_IS_ENABLED(PINCONF) + .pinconf_num_params = ARRAY_SIZE(uniphier_pinconf_params), + .pinconf_params = uniphier_pinconf_params, + .pinconf_group_set = uniphier_pinconf_group_set, +#endif .set_state = pinctrl_generic_set_state, };
diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-ld11.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-ld11.c index 1d318d8..53c37cd 100644 --- a/drivers/pinctrl/uniphier/pinctrl-uniphier-ld11.c +++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-ld11.c @@ -92,7 +92,8 @@ static struct uniphier_pinctrl_socdata uniphier_ld11_pinctrl_socdata = { .groups_count = ARRAY_SIZE(uniphier_ld11_groups), .functions = uniphier_ld11_functions, .functions_count = ARRAY_SIZE(uniphier_ld11_functions), - .caps = UNIPHIER_PINCTRL_CAPS_PERPIN_IECTRL, + .caps = UNIPHIER_PINCTRL_CAPS_PUPD_SIMPLE | + UNIPHIER_PINCTRL_CAPS_PERPIN_IECTRL, };
static int uniphier_ld11_pinctrl_probe(struct udevice *dev) diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-ld20.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-ld20.c index 0c46450..5a7d142 100644 --- a/drivers/pinctrl/uniphier/pinctrl-uniphier-ld20.c +++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-ld20.c @@ -106,7 +106,8 @@ static struct uniphier_pinctrl_socdata uniphier_ld20_pinctrl_socdata = { .groups_count = ARRAY_SIZE(uniphier_ld20_groups), .functions = uniphier_ld20_functions, .functions_count = ARRAY_SIZE(uniphier_ld20_functions), - .caps = UNIPHIER_PINCTRL_CAPS_PERPIN_IECTRL, + .caps = UNIPHIER_PINCTRL_CAPS_PUPD_SIMPLE | + UNIPHIER_PINCTRL_CAPS_PERPIN_IECTRL, };
static int uniphier_ld20_pinctrl_probe(struct udevice *dev) diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-ld6b.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-ld6b.c index 80d782c..b25c7ea 100644 --- a/drivers/pinctrl/uniphier/pinctrl-uniphier-ld6b.c +++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-ld6b.c @@ -140,6 +140,7 @@ static struct uniphier_pinctrl_socdata uniphier_ld6b_pinctrl_socdata = { .groups_count = ARRAY_SIZE(uniphier_ld6b_groups), .functions = uniphier_ld6b_functions, .functions_count = ARRAY_SIZE(uniphier_ld6b_functions), + .caps = UNIPHIER_PINCTRL_CAPS_PUPD_SIMPLE, };
static int uniphier_ld6b_pinctrl_probe(struct udevice *dev) diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-pro5.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-pro5.c index 9670f25..70c90ba 100644 --- a/drivers/pinctrl/uniphier/pinctrl-uniphier-pro5.c +++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-pro5.c @@ -147,7 +147,8 @@ static struct uniphier_pinctrl_socdata uniphier_pro5_pinctrl_socdata = { .groups_count = ARRAY_SIZE(uniphier_pro5_groups), .functions = uniphier_pro5_functions, .functions_count = ARRAY_SIZE(uniphier_pro5_functions), - .caps = UNIPHIER_PINCTRL_CAPS_DBGMUX_SEPARATE, + .caps = UNIPHIER_PINCTRL_CAPS_PUPD_SIMPLE | + UNIPHIER_PINCTRL_CAPS_DBGMUX_SEPARATE, };
static int uniphier_pro5_pinctrl_probe(struct udevice *dev) diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c index 1d29170..60777c3 100644 --- a/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c +++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-pxs2.c @@ -140,6 +140,7 @@ static struct uniphier_pinctrl_socdata uniphier_pxs2_pinctrl_socdata = { .groups_count = ARRAY_SIZE(uniphier_pxs2_groups), .functions = uniphier_pxs2_functions, .functions_count = ARRAY_SIZE(uniphier_pxs2_functions), + .caps = UNIPHIER_PINCTRL_CAPS_PUPD_SIMPLE, };
static int uniphier_pxs2_pinctrl_probe(struct udevice *dev) diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier.h b/drivers/pinctrl/uniphier/pinctrl-uniphier.h index 21e2d37..a0eccf8 100644 --- a/drivers/pinctrl/uniphier/pinctrl-uniphier.h +++ b/drivers/pinctrl/uniphier/pinctrl-uniphier.h @@ -67,6 +67,7 @@ struct uniphier_pinctrl_socdata { const char * const *functions; int functions_count; unsigned caps; +#define UNIPHIER_PINCTRL_CAPS_PUPD_SIMPLE BIT(3) #define UNIPHIER_PINCTRL_CAPS_PERPIN_IECTRL BIT(2) #define UNIPHIER_PINCTRL_CAPS_DBGMUX_SEPARATE BIT(1) #define UNIPHIER_PINCTRL_CAPS_MUX_4BIT BIT(0)

For the memory footprint reason, the Boot ROM can not load the ARM Trusted Firmware BL1 directly when Trusted Board Boot is enabled. The second stage loader is Socionext's own firmware, so rename it for clarification.
Signed-off-by: Masahiro Yamada yamada.masahiro@socionext.com ---
include/configs/uniphier.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/configs/uniphier.h b/include/configs/uniphier.h index b453d8f..ba9a504 100644 --- a/include/configs/uniphier.h +++ b/include/configs/uniphier.h @@ -144,7 +144,7 @@ #if defined(CONFIG_ARM64) && !defined(CONFIG_ARMV8_MULTIENTRY) /* ARM Trusted Firmware */ #define BOOT_IMAGES \ - "second_image=bl1.bin\0" \ + "second_image=unph_bl.bin\0" \ "third_image=fip.bin\0" #else #define BOOT_IMAGES \

2017-02-12 18:21 GMT+09:00 Masahiro Yamada yamada.masahiro@socionext.com:
For the memory footprint reason, the Boot ROM can not load the ARM Trusted Firmware BL1 directly when Trusted Board Boot is enabled. The second stage loader is Socionext's own firmware, so rename it for clarification.
Signed-off-by: Masahiro Yamada yamada.masahiro@socionext.com
Applied to u-boot-uniphier.

2017-02-12 18:21 GMT+09:00 Masahiro Yamada yamada.masahiro@socionext.com:
Support the following DT properties: "bias-disable" "bias-pull-up" "bias-pull-down" "bias-pull-pin-default" "input-enable" "input-disable"
My main motivation is to support pull up/down biasing. For Pro5 and later SoCs, the pupdctrl register number is the same as the pinmux number, so this feature can be supported without having big pin tables.
Signed-off-by: Masahiro Yamada yamada.masahiro@socionext.com
Applied to u-boot-uniphier.
participants (1)
-
Masahiro Yamada