
Hi Masahiro,
On 1 September 2015 at 07:50, Masahiro Yamada yamada.masahiro@socionext.com wrote:
The core support for the pinctrl drivers for all the UniPhier SoCs.
Signed-off-by: Masahiro Yamada yamada.masahiro@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@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@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@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