[U-Boot] [PATCH 01/15] pinctrl: uniphier: add UniPhier pinctrl core support
Simon Glass
sjg at chromium.org
Wed Sep 2 04:48:35 CEST 2015
Hi Masahiro,
On 1 September 2015 at 07:50, Masahiro Yamada
<yamada.masahiro at socionext.com> wrote:
> The core support for the pinctrl drivers for all the UniPhier SoCs.
>
> Signed-off-by: Masahiro Yamada <yamada.masahiro at socionext.com>
> ---
>
> drivers/pinctrl/Kconfig | 2 +
> drivers/pinctrl/Makefile | 2 +
> drivers/pinctrl/uniphier/Kconfig | 6 +
> drivers/pinctrl/uniphier/Makefile | 1 +
> drivers/pinctrl/uniphier/pinctrl-uniphier-core.c | 134 +++++++++++++++++++++++
> drivers/pinctrl/uniphier/pinctrl-uniphier.h | 57 ++++++++++
> 6 files changed, 202 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
Reviewed-by: Simon Glass <sjg at chromium.org>
A few comments below.
>
> diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
> index 30b8e45..9c12429 100644
> --- a/drivers/pinctrl/Kconfig
> +++ b/drivers/pinctrl/Kconfig
> @@ -106,4 +106,6 @@ config PINCTRL_SANDBOX
>
> endif
>
> +source "drivers/pinctrl/uniphier/Kconfig"
> +
> endmenu
> diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
> index 35decf4..d0eb263 100644
> --- a/drivers/pinctrl/Makefile
> +++ b/drivers/pinctrl/Makefile
> @@ -2,3 +2,5 @@ obj-y += pinctrl-uclass.o
> obj-$(CONFIG_$(SPL_)PINCTRL_GENERIC) += pinctrl-generic.o
>
> obj-$(CONFIG_PINCTRL_SANDBOX) += pinctrl-sandbox.o
> +
> +obj-$(CONFIG_ARCH_UNIPHIER) += uniphier/
> diff --git a/drivers/pinctrl/uniphier/Kconfig b/drivers/pinctrl/uniphier/Kconfig
> new file mode 100644
> index 0000000..29a623d
> --- /dev/null
> +++ b/drivers/pinctrl/uniphier/Kconfig
> @@ -0,0 +1,6 @@
> +if ARCH_UNIPHIER
> +
> +config PINCTRL_UNIPHIER_CORE
> + bool
> +
> +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..f008aea
> --- /dev/null
> +++ b/drivers/pinctrl/uniphier/pinctrl-uniphier-core.c
> @@ -0,0 +1,134 @@
> +/*
> + * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro at 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"
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +static int uniphier_pinctrl_get_groups_count(struct udevice *dev)
> +{
> + struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
> +
> + return priv->socdata->groups_count;
> +}
> +
> +static const char *uniphier_pinctrl_get_group_name(struct udevice *dev,
> + unsigned selector)
> +{
> + struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
> +
> + return priv->socdata->groups[selector].name;
> +}
> +
> +static int uniphier_pinmux_get_functions_count(struct udevice *dev)
> +{
> + struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
> +
> + return priv->socdata->functions_count;
> +}
> +
> +static const char *uniphier_pinmux_get_function_name(struct udevice *dev,
> + unsigned selector)
> +{
> + struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
> +
> + return priv->socdata->functions[selector];
> +}
> +
> +static void uniphier_pinmux_set_one(struct udevice *dev, unsigned pin,
> + unsigned muxval)
> +{
> + struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
> + unsigned mux_bits = priv->socdata->mux_bits;
> + unsigned reg_stride = priv->socdata->reg_stride;
> + 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_group_set(struct udevice *dev,
> + unsigned group_selector,
> + unsigned func_selector)
> +{
> + struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
> + const struct uniphier_pinctrl_group *group =
> + &priv->socdata->groups[group_selector];
> + const struct uniphier_pmx_data *pmx_data = group->pmx_data;
> + const unsigned num_pmx_data = group->num_pmx_data;
> + int i;
> +
> + for (i = 0; i < num_pmx_data; i++)
> + uniphier_pinmux_set_one(dev, pmx_data[i].pin,
> + pmx_data[i].muxval);
> +
> + return 0;
> +}
> +
> +const struct pinctrl_ops uniphier_pinctrl_ops = {
> + .get_groups_count = uniphier_pinctrl_get_groups_count,
> + .get_group_name = uniphier_pinctrl_get_group_name,
> + .get_functions_count = uniphier_pinmux_get_functions_count,
> + .get_function_name = uniphier_pinmux_get_function_name,
> + .pinmux_group_set = uniphier_pinmux_group_set,
> + .set_state = pinctrl_generic_set_state,
> +};
> +
> +int uniphier_pinctrl_probe(struct udevice *dev,
> + struct uniphier_pinctrl_socdata *socdata)
> +{
> + struct uniphier_pinctrl_priv *priv = dev_get_priv(dev);
> + 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..db74838
> --- /dev/null
> +++ b/drivers/pinctrl/uniphier/pinctrl-uniphier.h
> @@ -0,0 +1,57 @@
> +/*
> + * Copyright (C) 2015 Masahiro Yamada <yamada.masahiro at socionext.com>
> + *
> + * SPDX-License-Identifier: GPL-2.0+
> + */
> +
> +#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
Since this is local data you don't really need the UNIPHIER prefix,
but it's up to you.
> +
> +struct uniphier_pmx_data {
comments please on these structures.
> + unsigned pin;
> + unsigned muxval;
> +};
> +
> +struct uniphier_pinctrl_group {
> + const char *name;
> + const struct uniphier_pmx_data *pmx_data;
> + unsigned num_pmx_data;
> +};
> +
> +struct uniphier_pinctrl_socdata {
> + const struct uniphier_pinctrl_group *groups;
> + int groups_count;
> + const char * const *functions;
> + int functions_count;
> + unsigned mux_bits;
> + unsigned reg_stride;
> + bool load_pinctrl;
> +};
> +
> +#define UNIPHIER_PINCTRL_GROUP(grp) \
> + { \
> + .name = #grp, \
> + .pmx_data = grp##_pmx, \
> + .num_pmx_data = ARRAY_SIZE(grp##_pmx), \
> + }
> +
> +struct uniphier_pinctrl_priv {
> + void __iomem *base;
> + struct uniphier_pinctrl_socdata *socdata;
> +};
> +
> +extern const struct pinctrl_ops uniphier_pinctrl_ops;
It's a shame this cannot be static...
> +
> +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
>
Regards,
Simon
More information about the U-Boot
mailing list