Hi Masahiro, On 1 September 2015 at 07:50, Masahiro Yamada <[email protected]> wrote: > The core support for the pinctrl drivers for all the UniPhier SoCs. > > Signed-off-by: Masahiro Yamada <[email protected]> > --- > > 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 <[email protected]> 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 <[email protected]> > + * > + * 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 <[email protected]> > + * > + * 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 _______________________________________________ U-Boot mailing list [email protected] http://lists.denx.de/mailman/listinfo/u-boot

