The core support for the pinctrl drivers for all the UniPhier SoCs. Signed-off-by: Masahiro Yamada <yamada.masah...@socionext.com> ---
drivers/pinctrl/Kconfig | 2 + drivers/pinctrl/Makefile | 2 + drivers/pinctrl/uniphier/Kconfig | 7 ++ drivers/pinctrl/uniphier/Makefile | 1 + drivers/pinctrl/uniphier/pinctrl-uniphier-core.c | 127 +++++++++++++++++++++++ drivers/pinctrl/uniphier/pinctrl-uniphier.h | 51 +++++++++ 6 files changed, 190 insertions(+) create mode 100644 drivers/pinctrl/uniphier/Kconfig create mode 100644 drivers/pinctrl/uniphier/Makefile create mode 100644 drivers/pinctrl/uniphier/pinctrl-uniphier-core.c create mode 100644 drivers/pinctrl/uniphier/pinctrl-uniphier.h diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index cae4d55..758b5c7 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -1,2 +1,4 @@ config PINCTRL bool + +source "drivers/pinctrl/uniphier/Kconfig" diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index a775a4c..2af6887 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -1 +1,3 @@ obj-y += pinctrl-uclass.o + +obj-$(CONFIG_ARCH_UNIPHIER) += uniphier/ diff --git a/drivers/pinctrl/uniphier/Kconfig b/drivers/pinctrl/uniphier/Kconfig new file mode 100644 index 0000000..d458394 --- /dev/null +++ b/drivers/pinctrl/uniphier/Kconfig @@ -0,0 +1,7 @@ +if ARCH_UNIPHIER + +config PINCTRL_UNIPHIER_CORE + bool + select PINCTRL + +endif diff --git a/drivers/pinctrl/uniphier/Makefile b/drivers/pinctrl/uniphier/Makefile new file mode 100644 index 0000000..748aa1b --- /dev/null +++ b/drivers/pinctrl/uniphier/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_PINCTRL_UNIPHIER_CORE) += pinctrl-uniphier-core.o diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier-core.c b/drivers/pinctrl/uniphier/pinctrl-uniphier-core.c new file mode 100644 index 0000000..6436a30 --- /dev/null +++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-core.c @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2015 Masahiro Yamada <yamada.masah...@socionext.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <mapmem.h> +#include <linux/io.h> +#include <linux/err.h> +#include <dm/device.h> +#include <dm/pinctrl.h> + +#include "pinctrl-uniphier.h" + +static void uniphier_pinmux_set_one(struct udevice *dev, + const struct uniphier_mux *mux) +{ + struct uniphier_pinctrl_priv *priv = dev_get_priv(dev); + unsigned mux_bits = priv->socdata->mux_bits; + unsigned reg_stride = priv->socdata->reg_stride; + unsigned pin = mux->pin; + unsigned muxval = mux->muxval; + unsigned reg, reg_end, shift, mask; + u32 tmp; + + reg = UNIPHIER_PINCTRL_PINMUX_BASE + pin * mux_bits / 32 * reg_stride; + reg_end = reg + reg_stride; + shift = pin * mux_bits % 32; + mask = (1U << mux_bits) - 1; + + /* + * If reg_stride is greater than 4, the MSB of each pinsel shall be + * stored in the offset+4. + */ + for (; reg < reg_end; reg += 4) { + tmp = readl(priv->base + reg); + tmp &= ~(mask << shift); + tmp |= (mask & muxval) << shift; + writel(tmp, priv->base + reg); + + muxval >>= mux_bits; + } + + if (priv->socdata->load_pinctrl) + writel(1, priv->base + UNIPHIER_PINCTRL_LOAD_PINMUX); +} + +static int uniphier_pinmux_set(struct udevice *dev, const char *group, + const char *function) +{ + struct uniphier_pinctrl_priv *priv = dev_get_priv(dev); + const struct uniphier_pinmux_data *pinmux_data = + priv->socdata->pinmux_data; + const unsigned num_pinmux_data = priv->socdata->num_pinmux_data; + const struct uniphier_mux *mux; + unsigned nmux; + int i; + + for (i = 0; i < num_pinmux_data; i++) { + if (strcmp(pinmux_data[i].function, function)) + continue; + + if (!group || !strcmp(pinmux_data[i].group, group)) + break; + } + + if (i >= num_pinmux_data) { + printf("unsupported pinmux: group = %s, functions = %s\n", + group, function); + return -EINVAL; + } + + mux = pinmux_data[i].muxdata; + nmux = pinmux_data[i].num_muxdata; + + for (i = 0; i < nmux; i++) + uniphier_pinmux_set_one(dev, &mux[i]); + + return 0; +} + +static int uniphier_pinconf_set(struct udevice *dev, const char *group, + const char *conf_param, unsigned conf_arg) +{ + /* not implemented yet: just debug message */ + printf("%s: pinconf_set, group = %s, conf_param = %s, conf_arg = %d\n", + dev->name, group, conf_param, conf_arg); + + return 0; +} + +const struct pinctrl_ops uniphier_pinctrl_ops = { + .pinmux_set = uniphier_pinmux_set, + .pinconf_set = uniphier_pinconf_set, +}; + +int uniphier_pinctrl_probe(struct udevice *dev, + struct uniphier_pinctrl_socdata *socdata) +{ + struct uniphier_pinctrl_priv *priv = dev_get_priv(dev); + DECLARE_GLOBAL_DATA_PTR; + fdt_addr_t addr; + fdt_size_t size; + + addr = fdtdec_get_addr_size(gd->fdt_blob, dev->of_offset, "reg", + &size); + if (addr == FDT_ADDR_T_NONE) + return -EINVAL; + + priv->base = map_sysmem(addr, size); + if (!priv->base) + return -ENOMEM; + + priv->socdata = socdata; + + return 0; +} + +int uniphier_pinctrl_remove(struct udevice *dev) +{ + struct uniphier_pinctrl_priv *priv = dev_get_priv(dev); + + unmap_sysmem(priv->base); + + return 0; +} diff --git a/drivers/pinctrl/uniphier/pinctrl-uniphier.h b/drivers/pinctrl/uniphier/pinctrl-uniphier.h new file mode 100644 index 0000000..681158b --- /dev/null +++ b/drivers/pinctrl/uniphier/pinctrl-uniphier.h @@ -0,0 +1,51 @@ +#ifndef __PINCTRL_UNIPHIER_H__ +#define __PINCTRL_UNIPHIER_H__ + +#include <linux/kernel.h> +#include <linux/types.h> + +#define UNIPHIER_PINCTRL_PINMUX_BASE 0x0 +#define UNIPHIER_PINCTRL_LOAD_PINMUX 0x700 +#define UNIPHIER_PINCTRL_IECTRL 0xd00 + +struct uniphier_mux { + unsigned pin; + unsigned muxval; +}; + +struct uniphier_pinmux_data { + const char *group; + const char *function; + const struct uniphier_mux *muxdata; + unsigned num_muxdata; +}; + +struct uniphier_pinctrl_socdata { + const struct uniphier_pinmux_data *pinmux_data; + unsigned num_pinmux_data; + unsigned mux_bits; + unsigned reg_stride; + bool load_pinctrl; +}; + +#define UNIPHIER_PINMUX_DATA(grp, func) \ + { \ + .group = #grp, \ + .function = #func, \ + .muxdata = grp##_mux, \ + .num_muxdata = ARRAY_SIZE(grp##_mux), \ + } + +struct uniphier_pinctrl_priv { + void __iomem *base; + struct uniphier_pinctrl_socdata *socdata; +}; + +extern const struct pinctrl_ops uniphier_pinctrl_ops; + +int uniphier_pinctrl_probe(struct udevice *dev, + struct uniphier_pinctrl_socdata *socdata); + +int uniphier_pinctrl_remove(struct udevice *dev); + +#endif /* __PINCTRL_UNIPHIER_H__ */ -- 1.9.1 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot