[U-Boot] [PATCH 01/15] pinctrl: uniphier: add UniPhier pinctrl core support
Masahiro Yamada
yamada.masahiro at socionext.com
Tue Sep 1 15:50:18 CEST 2015
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
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
+
+struct uniphier_pmx_data {
+ 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;
+
+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
More information about the U-Boot
mailing list