2014-04-23 15:51:23

by Antoine Tenart

[permalink] [raw]
Subject: [PATCH v2 0/7] ARM: berlin: add pinctrl support

This series adds support for the Marvell Berlin pin-controller, allowing
to configure the pin muxing from the device tree.

The Berlin pin-controller support is divided into 3 drivers, each
driving one Berlin SoC. These drivers use a Berlin common part.

This series applies on top of patches introducing the Marvell Berlin
BG2Q you can find on Sebastian's berlin/for-next branch[1] and the patch
allowing not to define the get_group_pins() function[2].

Tested on the Berlin BG2Q.

[1] https://github.com/shesselba/linux-berlin/commits/berlin/for-next
[2] https://patchwork.kernel.org/patch/3964491/

Changes since v1:
- moved the driver to a specific berlin/ directory
- divided the pin-controller driver into three (one per SoC) and
reworked the driver dependencies accordingly
- reworked the device tree bindings
- removed the reg-names and reworked the driver to allow
splitting the two pin-controllers into two separate nodes in
the device tree
- updated the documentation
- removed unnecessary checks
- added support to mux multiple groups with the same function
- added BG2, BG2 and BG2CD function definitions

Antoine Ténart (7):
pinctrl: berlin: add the core pinctrl driver for Marvell Berlin SoCs
pinctrl: berlin: add the BG2Q pinctrl driver
pinctrl: berlin: add the BG2 pinctrl driver
pinctrl: berlin: add the BG2CD pinctrl driver
ARM: berlin: add the pinctrl dependency for the Marvell Berlin SoCs
Documentation: add the Marvell Berlin pinctrl documentation
ARM: dts: berlin: add the pinctrl node and muxing setup for uarts

.../bindings/pinctrl/marvell,berlin-pinctrl.txt | 44 +++
arch/arm/boot/dts/berlin2.dtsi | 24 ++
arch/arm/boot/dts/berlin2cd.dtsi | 17 +
arch/arm/boot/dts/berlin2q.dtsi | 24 ++
arch/arm/mach-berlin/Kconfig | 4 +
drivers/pinctrl/Kconfig | 1 +
drivers/pinctrl/Makefile | 1 +
drivers/pinctrl/berlin/Kconfig | 19 +
drivers/pinctrl/berlin/Makefile | 4 +
drivers/pinctrl/berlin/berlin-bg2.c | 251 +++++++++++++
drivers/pinctrl/berlin/berlin-bg2cd.c | 194 ++++++++++
drivers/pinctrl/berlin/berlin-bg2q.c | 413 +++++++++++++++++++++
drivers/pinctrl/berlin/berlin.c | 347 +++++++++++++++++
drivers/pinctrl/berlin/berlin.h | 71 ++++
14 files changed, 1414 insertions(+)
create mode 100644 Documentation/devicetree/bindings/pinctrl/marvell,berlin-pinctrl.txt
create mode 100644 drivers/pinctrl/berlin/Kconfig
create mode 100644 drivers/pinctrl/berlin/Makefile
create mode 100644 drivers/pinctrl/berlin/berlin-bg2.c
create mode 100644 drivers/pinctrl/berlin/berlin-bg2cd.c
create mode 100644 drivers/pinctrl/berlin/berlin-bg2q.c
create mode 100644 drivers/pinctrl/berlin/berlin.c
create mode 100644 drivers/pinctrl/berlin/berlin.h

--
1.8.3.2


2014-04-23 15:51:33

by Antoine Tenart

[permalink] [raw]
Subject: [PATCH v2 5/7] ARM: berlin: add the pinctrl dependency for the Marvell Berlin SoCs

Signed-off-by: Antoine Ténart <[email protected]>
---
arch/arm/mach-berlin/Kconfig | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/arch/arm/mach-berlin/Kconfig b/arch/arm/mach-berlin/Kconfig
index d3c5f14dc142..9c2b569e54ba 100644
--- a/arch/arm/mach-berlin/Kconfig
+++ b/arch/arm/mach-berlin/Kconfig
@@ -4,6 +4,7 @@ config ARCH_BERLIN
select GENERIC_IRQ_CHIP
select DW_APB_ICTL
select DW_APB_TIMER_OF
+ select PINCTRL

if ARCH_BERLIN

@@ -14,11 +15,13 @@ config MACH_BERLIN_BG2
select CACHE_L2X0
select CPU_PJ4B
select HAVE_ARM_TWD if SMP
+ select PINCTRL_BERLIN_BG2

config MACH_BERLIN_BG2CD
bool "Marvell Armada 1500-mini (BG2CD)"
select CACHE_L2X0
select HAVE_ARM_TWD if SMP
+ select PINCTRL_BERLIN_BG2CD

config MACH_BERLIN_BG2Q
bool "Marvell Armada 1500 Pro (BG2-Q)"
@@ -26,6 +29,7 @@ config MACH_BERLIN_BG2Q
select CPU_V7
select HAVE_ARM_TWD if SMP
select HAVE_SMP
+ select PINCTRL_BERLIN_BG2Q

endmenu

--
1.8.3.2

2014-04-23 15:51:31

by Antoine Tenart

[permalink] [raw]
Subject: [PATCH v2 3/7] pinctrl: berlin: add the BG2 pinctrl driver

Add the pin-controller driver for the Berlin BG2 SoC, with definition
of its groups and functions. This uses the core Berlin pinctrl driver.

Signed-off-by: Antoine Ténart <[email protected]>
---
drivers/pinctrl/berlin/Kconfig | 4 +
drivers/pinctrl/berlin/Makefile | 1 +
drivers/pinctrl/berlin/berlin-bg2.c | 251 ++++++++++++++++++++++++++++++++++++
3 files changed, 256 insertions(+)
create mode 100644 drivers/pinctrl/berlin/berlin-bg2.c

diff --git a/drivers/pinctrl/berlin/Kconfig b/drivers/pinctrl/berlin/Kconfig
index 58ecfd797dd8..1b34943bef1c 100644
--- a/drivers/pinctrl/berlin/Kconfig
+++ b/drivers/pinctrl/berlin/Kconfig
@@ -4,6 +4,10 @@ config PINCTRL_BERLIN
bool
select PINMUX

+config PINCTRL_BERLIN_BG2
+ bool
+ select PINCTRL_BERLIN
+
config PINCTRL_BERLIN_BG2Q
bool
select PINCTRL_BERLIN
diff --git a/drivers/pinctrl/berlin/Makefile b/drivers/pinctrl/berlin/Makefile
index 1866b1f2d1cf..e37e4e7a8838 100644
--- a/drivers/pinctrl/berlin/Makefile
+++ b/drivers/pinctrl/berlin/Makefile
@@ -1,2 +1,3 @@
obj-$(CONFIG_PINCTRL_BERLIN) += berlin.o
+obj-$(CONFIG_PINCTRL_BERLIN_BG2) += berlin-bg2.o
obj-$(CONFIG_PINCTRL_BERLIN_BG2Q) += berlin-bg2q.o
diff --git a/drivers/pinctrl/berlin/berlin-bg2.c b/drivers/pinctrl/berlin/berlin-bg2.c
new file mode 100644
index 000000000000..4a4efdc2232d
--- /dev/null
+++ b/drivers/pinctrl/berlin/berlin-bg2.c
@@ -0,0 +1,251 @@
+/*
+ * Marvell Berlin BG2 pinctrl driver.
+ *
+ * Copyright (C) 2014 Marvell Technology Group Ltd.
+ *
+ * Antoine Ténart <[email protected]>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+
+#include "berlin.h"
+
+static const struct berlin_desc_group berlin2_soc_pinctrl_groups[] = {
+ /* G */
+ BERLIN_PINCTRL_GROUP("G0", 0x00, 0x1, 0x00,
+ BERLIN_PINCTRL_FUNCTION(0x0, "spi1"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "gpio")),
+ BERLIN_PINCTRL_GROUP("G1", 0x00, 0x2, 0x01,
+ BERLIN_PINCTRL_FUNCTION(0x0, "spi1"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "usb1")),
+ BERLIN_PINCTRL_GROUP("G2", 0x00, 0x2, 0x02,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "spi1"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "pwm"),
+ BERLIN_PINCTRL_FUNCTION(0x3, "i2s0")),
+ BERLIN_PINCTRL_GROUP("G3", 0x00, 0x2, 0x04,
+ BERLIN_PINCTRL_FUNCTION(0x0, "soc"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "spi1"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x3, "i2s1")),
+ BERLIN_PINCTRL_GROUP("G4", 0x00, 0x2, 0x06,
+ BERLIN_PINCTRL_FUNCTION(0x0, "spi1"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "pwm")),
+ BERLIN_PINCTRL_GROUP("G5", 0x00, 0x3, 0x08,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "sts1"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "et"),
+ /*
+ * Mode 0x3 mux i2s2 mclk *and* i2s3 mclk:
+ * add two functions so it can be used with other groups
+ * within the same subnode in the device tree
+ */
+ BERLIN_PINCTRL_FUNCTION(0x3, "i2s2"),
+ BERLIN_PINCTRL_FUNCTION(0x3, "i2s3")),
+ BERLIN_PINCTRL_GROUP("G6", 0x00, 0x2, 0x0b,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "sts0"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "et")),
+ BERLIN_PINCTRL_GROUP("G7", 0x00, 0x3, 0x0d,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "sts0"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "et"),
+ BERLIN_PINCTRL_FUNCTION(0x3, "vdac")),
+ BERLIN_PINCTRL_GROUP("G8", 0x00, 0x3, 0x10,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "sd0"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "et"),
+ BERLIN_PINCTRL_FUNCTION(0x3, "usb0_dbg"),
+ BERLIN_PINCTRL_FUNCTION(0x4, "sata_dbg"),
+ BERLIN_PINCTRL_FUNCTION(0x7, "usb1_dbg")),
+ BERLIN_PINCTRL_GROUP("G9", 0x00, 0x3, 0x13,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "sd0"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "et"),
+ BERLIN_PINCTRL_FUNCTION(0x3, "usb0_dbg"),
+ BERLIN_PINCTRL_FUNCTION(0x4, "sata_dbg"),
+ BERLIN_PINCTRL_FUNCTION(0x7, "usb1_dbg")),
+ BERLIN_PINCTRL_GROUP("G10", 0x00, 0x2, 0x16,
+ BERLIN_PINCTRL_FUNCTION(0x0, "soc"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "tw0"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x3, "ptp")),
+ BERLIN_PINCTRL_GROUP("G11", 0x00, 0x2, 0x18,
+ BERLIN_PINCTRL_FUNCTION(0x0, "soc"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "tw1"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x3, "eddc")),
+ BERLIN_PINCTRL_GROUP("G12", 0x00, 0x3, 0x1a,
+ BERLIN_PINCTRL_FUNCTION(0x0, "sts2"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "sata"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "sd1"),
+ BERLIN_PINCTRL_FUNCTION(0x3, "usb0_dbg"),
+ BERLIN_PINCTRL_FUNCTION(0x4, "sts1"),
+ BERLIN_PINCTRL_FUNCTION(0x7, "usb1_dbg")),
+ BERLIN_PINCTRL_GROUP("G13", 0x04, 0x3, 0x00,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "sata"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "sd1"),
+ BERLIN_PINCTRL_FUNCTION(0x3, "usb0_dbg"),
+ BERLIN_PINCTRL_FUNCTION(0x4, "sts1"),
+ BERLIN_PINCTRL_FUNCTION(0x7, "usb1_dbg")),
+ BERLIN_PINCTRL_GROUP("G14", 0x04, 0x1, 0x03,
+ BERLIN_PINCTRL_FUNCTION_UNKNOW),
+ BERLIN_PINCTRL_GROUP("G15", 0x04, 0x2, 0x04,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "et"),
+ BERLIN_PINCTRL_FUNCTION(0x3, "osco")),
+ BERLIN_PINCTRL_GROUP("G16", 0x04, 0x3, 0x06,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "dvio"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "fp")),
+ BERLIN_PINCTRL_GROUP("G17", 0x04, 0x3, 0x09,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "dvio"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "fp")),
+ BERLIN_PINCTRL_GROUP("G18", 0x04, 0x1, 0x0c,
+ BERLIN_PINCTRL_FUNCTION(0x0, "pll"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "i2s0")),
+ BERLIN_PINCTRL_GROUP("G19", 0x04, 0x1, 0x0d,
+ BERLIN_PINCTRL_FUNCTION(0x0, "i2s0"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "pwm")),
+ BERLIN_PINCTRL_GROUP("G20", 0x04, 0x1, 0x0e,
+ BERLIN_PINCTRL_FUNCTION(0x0, "spdif"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "arc")),
+ BERLIN_PINCTRL_GROUP("G21", 0x04, 0x3, 0x0f,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "dvio"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "fp"),
+ BERLIN_PINCTRL_FUNCTION(0x3, "adac_dbg"),
+ BERLIN_PINCTRL_FUNCTION(0x4, "pdm_a"), /* gpio17..19,pdm */
+ BERLIN_PINCTRL_FUNCTION(0x7, "pdm_b")), /* gpio12..14,pdm */
+ BERLIN_PINCTRL_GROUP("G22", 0x04, 0x3, 0x12,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "dv0"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "fp"),
+ BERLIN_PINCTRL_FUNCTION(0x3, "tw0"),
+ BERLIN_PINCTRL_FUNCTION(0x4, "pwm")),
+ BERLIN_PINCTRL_GROUP("G23", 0x04, 0x3, 0x15,
+ BERLIN_PINCTRL_FUNCTION(0x0, "vclki"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "dv0"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "fp"),
+ BERLIN_PINCTRL_FUNCTION(0x3, "i2s0"),
+ BERLIN_PINCTRL_FUNCTION(0x4, "pwm"),
+ BERLIN_PINCTRL_FUNCTION(0x7, "pdm")),
+ BERLIN_PINCTRL_GROUP("G24", 0x04, 0x2, 0x18,
+ BERLIN_PINCTRL_FUNCTION(0x0, "i2s2"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "i2s1")),
+ BERLIN_PINCTRL_GROUP("G25", 0x04, 0x2, 0x1a,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "nand"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "i2s2")),
+ BERLIN_PINCTRL_GROUP("G26", 0x04, 0x1, 0x1c,
+ BERLIN_PINCTRL_FUNCTION(0x0, "nand"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "emmc")),
+ BERLIN_PINCTRL_GROUP("G27", 0x04, 0x1, 0x1d,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "nand")),
+ BERLIN_PINCTRL_GROUP("G28", 0x04, 0x2, 0x1e,
+ BERLIN_PINCTRL_FUNCTION(0x0, "dvo"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "sp")),
+};
+
+static const struct berlin_desc_group berlin2_sysmgr_pinctrl_groups[] = {
+ /* GSM */
+ BERLIN_PINCTRL_GROUP("GSM0", 0x40, 0x2, 0x00,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "spi2"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "eth1")),
+ BERLIN_PINCTRL_GROUP("GSM1", 0x40, 0x2, 0x02,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "spi2"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "eth1")),
+ BERLIN_PINCTRL_GROUP("GSM2", 0x40, 0x2, 0x04,
+ BERLIN_PINCTRL_FUNCTION(0x0, "tw2"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "spi2")),
+ BERLIN_PINCTRL_GROUP("GSM3", 0x40, 0x2, 0x06,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "uart0"), /* CTS/RDS */
+ BERLIN_PINCTRL_FUNCTION(0x2, "uart2"), /* RX/TX */
+ BERLIN_PINCTRL_FUNCTION(0x3, "tw2")),
+ BERLIN_PINCTRL_GROUP("GSM4", 0x40, 0x2, 0x08,
+ BERLIN_PINCTRL_FUNCTION(0x0, "uart0"), /* RX/TX */
+ BERLIN_PINCTRL_FUNCTION(0x1, "irda0")),
+ BERLIN_PINCTRL_GROUP("GSM5", 0x40, 0x2, 0x0a,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "uart1"), /* RX/TX */
+ BERLIN_PINCTRL_FUNCTION(0x2, "irda1"),
+ BERLIN_PINCTRL_FUNCTION(0x3, "tw3")),
+ BERLIN_PINCTRL_GROUP("GSM6", 0x40, 0x2, 0x0c,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "spi2"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "clki")),
+ BERLIN_PINCTRL_GROUP("GSM7", 0x40, 0x1, 0x0e,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "hdmi")),
+ BERLIN_PINCTRL_GROUP("GSM8", 0x40, 0x1, 0x0f,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "hdmi")),
+ BERLIN_PINCTRL_GROUP("GSM9", 0x40, 0x1, 0x10,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "led")),
+ BERLIN_PINCTRL_GROUP("GSM10", 0x40, 0x1, 0x11,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "led")),
+ BERLIN_PINCTRL_GROUP("GSM11", 0x40, 0x1, 0x12,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "led")),
+};
+
+static const struct berlin_pinctrl_desc berlin2_soc_pinctrl_data = {
+ .groups = berlin2_soc_pinctrl_groups,
+ .ngroups = ARRAY_SIZE(berlin2_soc_pinctrl_groups),
+};
+
+static const struct berlin_pinctrl_desc berlin2_sysmgr_pinctrl_data = {
+ .groups = berlin2_sysmgr_pinctrl_groups,
+ .ngroups = ARRAY_SIZE(berlin2_sysmgr_pinctrl_groups),
+};
+
+static const struct of_device_id berlin2_pinctrl_match[] = {
+ {
+ .compatible = "marvell,berlin2-soc-pinctrl",
+ .data = &berlin2_soc_pinctrl_data
+ },
+ {
+ .compatible = "marvell,berlin2-sysmgr-pinctrl",
+ .data = &berlin2_sysmgr_pinctrl_data
+ },
+ {}
+};
+MODULE_DEVICE_TABLE(of, berlin2_pinctrl_match);
+
+static int berlin2_pinctrl_probe(struct platform_device *pdev)
+{
+ const struct of_device_id
+ *device = of_match_device(berlin2_pinctrl_match, &pdev->dev);
+
+ return berlin_pinctrl_probe(pdev, device->data);
+}
+
+static struct platform_driver berlin2_pinctrl_driver = {
+ .probe = berlin2_pinctrl_probe,
+ .driver = {
+ .name = "berlin-bg2-pinctrl",
+ .owner = THIS_MODULE,
+ .of_match_table = berlin2_pinctrl_match,
+ },
+};
+module_platform_driver(berlin2_pinctrl_driver);
+
+MODULE_AUTHOR("Antoine Ténart <[email protected]>");
+MODULE_DESCRIPTION("Marvell Berlin BG2 pinctrl driver");
+MODULE_LICENSE("GPL");
--
1.8.3.2

2014-04-23 15:51:29

by Antoine Tenart

[permalink] [raw]
Subject: [PATCH v2 6/7] Documentation: add the Marvell Berlin pinctrl documentation

Add the documentation related to the Berlin pin-controller driver and
explain how to configure this group based controller.

Signed-off-by: Antoine Ténart <[email protected]>
---
.../bindings/pinctrl/marvell,berlin-pinctrl.txt | 44 ++++++++++++++++++++++
1 file changed, 44 insertions(+)
create mode 100644 Documentation/devicetree/bindings/pinctrl/marvell,berlin-pinctrl.txt

diff --git a/Documentation/devicetree/bindings/pinctrl/marvell,berlin-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/marvell,berlin-pinctrl.txt
new file mode 100644
index 000000000000..c59671ac6b54
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/marvell,berlin-pinctrl.txt
@@ -0,0 +1,44 @@
+* Pin-controller driver for the Marvell Berlin SoCs
+
+The pins controlled by the Marvell Berlin controller are organized in groups.
+Configuration is done by group, so no actual pin information is needed.
+
+Be aware the Marvell Berlin datasheets use the keyword 'mode' for what is called
+a 'function' in the pin-controller subsystem.
+
+Required properties:
+- compatible: should be one of: "marvell,berlin2-soc-pinctrl",
+ "marvell,berlin2-sysmgr-pinctrl",
+ "marvell,berlin2cd-soc-pinctrl",
+ "marvell,berlin2cd-sysmgr-pinctrl",
+ "marvell,berlin2q-soc-pinctrl"
+ "marvell,berlin2q-sysmgr-pinctrl"
+- reg: registers physical address and length of the pin controller.
+
+Please refer to pinctrl-bindings.txt in this directory for details of the
+common pin-controller bindings used by client devices.
+
+A pin-controller node should contain subnodes representing the pin group
+configurations, one per group. Each subnode has the group name and the muxing
+function used.
+
+Required subnode-properties:
+- marvell,groups: a list of strings describing the group names.
+- marvell,function: a string describing the function used to mux the groups.
+
+Example:
+
+sm_pinctrl: pin-controller@0 {
+ compatible = "marvell,berlin2q-sysmgr-pinctrl";
+ reg = <0xfc0000 0x44>;
+
+ uart0_pmux: uart0-pmux {
+ marvell,groups = "GSM12", "GSM13";
+ marvell,function = "uart0";
+ };
+}
+
+&uart0 {
+ pinctrl-0 = <&uart0_pmux>;
+ pinctrl-names = "default";
+};
--
1.8.3.2

2014-04-23 15:51:27

by Antoine Tenart

[permalink] [raw]
Subject: [PATCH v2 4/7] pinctrl: berlin: add the BG2CD pinctrl driver

Add the pin-controller driver for the Berlin BG2CD SoC, with definition
of its groups and functions. This uses the core Berlin pinctrl driver.

Signed-off-by: Antoine Ténart <[email protected]>
---
drivers/pinctrl/berlin/Kconfig | 4 +
drivers/pinctrl/berlin/Makefile | 1 +
drivers/pinctrl/berlin/berlin-bg2cd.c | 194 ++++++++++++++++++++++++++++++++++
3 files changed, 199 insertions(+)
create mode 100644 drivers/pinctrl/berlin/berlin-bg2cd.c

diff --git a/drivers/pinctrl/berlin/Kconfig b/drivers/pinctrl/berlin/Kconfig
index 1b34943bef1c..b2cee6f71ccd 100644
--- a/drivers/pinctrl/berlin/Kconfig
+++ b/drivers/pinctrl/berlin/Kconfig
@@ -8,6 +8,10 @@ config PINCTRL_BERLIN_BG2
bool
select PINCTRL_BERLIN

+config PINCTRL_BERLIN_BG2CD
+ bool
+ select PINCTRL_BERLIN
+
config PINCTRL_BERLIN_BG2Q
bool
select PINCTRL_BERLIN
diff --git a/drivers/pinctrl/berlin/Makefile b/drivers/pinctrl/berlin/Makefile
index e37e4e7a8838..deb0c6baf316 100644
--- a/drivers/pinctrl/berlin/Makefile
+++ b/drivers/pinctrl/berlin/Makefile
@@ -1,3 +1,4 @@
obj-$(CONFIG_PINCTRL_BERLIN) += berlin.o
obj-$(CONFIG_PINCTRL_BERLIN_BG2) += berlin-bg2.o
+obj-$(CONFIG_PINCTRL_BERLIN_BG2CD) += berlin-bg2cd.o
obj-$(CONFIG_PINCTRL_BERLIN_BG2Q) += berlin-bg2q.o
diff --git a/drivers/pinctrl/berlin/berlin-bg2cd.c b/drivers/pinctrl/berlin/berlin-bg2cd.c
new file mode 100644
index 000000000000..a12da1828bc9
--- /dev/null
+++ b/drivers/pinctrl/berlin/berlin-bg2cd.c
@@ -0,0 +1,194 @@
+/*
+ * Marvell Berlin BG2CD pinctrl driver.
+ *
+ * Copyright (C) 2014 Marvell Technology Group Ltd.
+ *
+ * Antoine Ténart <[email protected]>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+
+#include "berlin.h"
+
+static const struct berlin_desc_group berlin2cd_soc_pinctrl_groups[] = {
+ /* G */
+ BERLIN_PINCTRL_GROUP("G0", 0x00, 0x1, 0x00,
+ BERLIN_PINCTRL_FUNCTION(0x0, "jtag"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "led"),
+ BERLIN_PINCTRL_FUNCTION(0x3, "pwm")),
+ BERLIN_PINCTRL_GROUP("G1", 0x00, 0x2, 0x01,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "sd0"),
+ BERLIN_PINCTRL_FUNCTION(0x6, "usb0_dbg"),
+ BERLIN_PINCTRL_FUNCTION(0x7, "usb1_dbg")),
+ BERLIN_PINCTRL_GROUP("G2", 0x00, 0x2, 0x02,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "sd0"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "fe"),
+ BERLIN_PINCTRL_FUNCTION(0x3, "pll"),
+ BERLIN_PINCTRL_FUNCTION(0x6, "usb0_dbg"),
+ BERLIN_PINCTRL_FUNCTION(0x7, "usb1_dbg")),
+ BERLIN_PINCTRL_GROUP("G3", 0x00, 0x2, 0x04,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "sd0"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "tw2"),
+ BERLIN_PINCTRL_FUNCTION(0x3, "pll"),
+ BERLIN_PINCTRL_FUNCTION(0x4, "fe"),
+ BERLIN_PINCTRL_FUNCTION(0x6, "usb0_dbg"),
+ BERLIN_PINCTRL_FUNCTION(0x7, "usb1_dbg")),
+ BERLIN_PINCTRL_GROUP("G4", 0x00, 0x2, 0x06,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "sd0"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "tw3"),
+ BERLIN_PINCTRL_FUNCTION(0x3, "pll"),
+ BERLIN_PINCTRL_FUNCTION(0x4, "pwm"),
+ BERLIN_PINCTRL_FUNCTION(0x6, "usb0_dbg"),
+ BERLIN_PINCTRL_FUNCTION(0x7, "usb1_dbg")),
+ BERLIN_PINCTRL_GROUP("G5", 0x00, 0x3, 0x08,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "sd0"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "tw3"),
+ BERLIN_PINCTRL_FUNCTION(0x3, "arc"),
+ BERLIN_PINCTRL_FUNCTION(0x4, "pwm"),
+ BERLIN_PINCTRL_FUNCTION(0x6, "usb0_dbg"),
+ BERLIN_PINCTRL_FUNCTION(0x7, "usb1_dbg")),
+ BERLIN_PINCTRL_GROUP("G6", 0x00, 0x2, 0x0b,
+ BERLIN_PINCTRL_FUNCTION(0x0, "uart0"), /* RX/TX */
+ BERLIN_PINCTRL_FUNCTION(0x1, "gpio")),
+ BERLIN_PINCTRL_GROUP("G7", 0x00, 0x3, 0x0d,
+ BERLIN_PINCTRL_FUNCTION(0x0, "eddc"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "tw1"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "gpio")),
+ BERLIN_PINCTRL_GROUP("G8", 0x00, 0x3, 0x10,
+ BERLIN_PINCTRL_FUNCTION(0x0, "ss0"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "gpio")),
+ BERLIN_PINCTRL_GROUP("G9", 0x00, 0x3, 0x13,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "spi1"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "tw0")),
+ BERLIN_PINCTRL_GROUP("G10", 0x00, 0x2, 0x16,
+ BERLIN_PINCTRL_FUNCTION(0x0, "spi1"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "gpio")),
+ BERLIN_PINCTRL_GROUP("G11", 0x00, 0x2, 0x18,
+ BERLIN_PINCTRL_FUNCTION(0x0, "spi1"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "gpio")),
+ BERLIN_PINCTRL_GROUP("G12", 0x00, 0x3, 0x1a,
+ BERLIN_PINCTRL_FUNCTION(0x0, "usb1"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "gpio")),
+ BERLIN_PINCTRL_GROUP("G13", 0x04, 0x3, 0x00,
+ BERLIN_PINCTRL_FUNCTION(0x0, "nand"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "usb0_dbg"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "usb1_dbg")),
+ BERLIN_PINCTRL_GROUP("G14", 0x04, 0x1, 0x03,
+ BERLIN_PINCTRL_FUNCTION(0x0, "nand"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "gpio")),
+ BERLIN_PINCTRL_GROUP("G15", 0x04, 0x2, 0x04,
+ BERLIN_PINCTRL_FUNCTION(0x0, "jtag"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "gpio")),
+ BERLIN_PINCTRL_GROUP("G16", 0x04, 0x3, 0x06,
+ BERLIN_PINCTRL_FUNCTION_UNKNOW),
+ BERLIN_PINCTRL_GROUP("G17", 0x04, 0x3, 0x09,
+ BERLIN_PINCTRL_FUNCTION_UNKNOW),
+ BERLIN_PINCTRL_GROUP("G18", 0x04, 0x1, 0x0c,
+ BERLIN_PINCTRL_FUNCTION_UNKNOW),
+ BERLIN_PINCTRL_GROUP("G19", 0x04, 0x1, 0x0d,
+ BERLIN_PINCTRL_FUNCTION_UNKNOW),
+ BERLIN_PINCTRL_GROUP("G20", 0x04, 0x1, 0x0e,
+ BERLIN_PINCTRL_FUNCTION_UNKNOW),
+ BERLIN_PINCTRL_GROUP("G21", 0x04, 0x3, 0x0f,
+ BERLIN_PINCTRL_FUNCTION_UNKNOW),
+ BERLIN_PINCTRL_GROUP("G22", 0x04, 0x3, 0x12,
+ BERLIN_PINCTRL_FUNCTION_UNKNOW),
+ BERLIN_PINCTRL_GROUP("G23", 0x04, 0x3, 0x15,
+ BERLIN_PINCTRL_FUNCTION_UNKNOW),
+ BERLIN_PINCTRL_GROUP("G24", 0x04, 0x2, 0x18,
+ BERLIN_PINCTRL_FUNCTION_UNKNOW),
+ BERLIN_PINCTRL_GROUP("G25", 0x04, 0x2, 0x1a,
+ BERLIN_PINCTRL_FUNCTION_UNKNOW),
+ BERLIN_PINCTRL_GROUP("G26", 0x04, 0x1, 0x1c,
+ BERLIN_PINCTRL_FUNCTION_UNKNOW),
+ BERLIN_PINCTRL_GROUP("G27", 0x04, 0x1, 0x1d,
+ BERLIN_PINCTRL_FUNCTION_UNKNOW),
+ BERLIN_PINCTRL_GROUP("G28", 0x04, 0x2, 0x1e,
+ BERLIN_PINCTRL_FUNCTION_UNKNOW),
+};
+
+static const struct berlin_desc_group berlin2cd_sysmgr_pinctrl_groups[] = {
+ /* GSM */
+ BERLIN_PINCTRL_GROUP("GSM0", 0x40, 0x2, 0x00,
+ BERLIN_PINCTRL_FUNCTION_UNKNOW),
+ BERLIN_PINCTRL_GROUP("GSM1", 0x40, 0x2, 0x02,
+ BERLIN_PINCTRL_FUNCTION_UNKNOW),
+ BERLIN_PINCTRL_GROUP("GSM2", 0x40, 0x2, 0x04,
+ BERLIN_PINCTRL_FUNCTION_UNKNOW),
+ BERLIN_PINCTRL_GROUP("GSM3", 0x40, 0x2, 0x06,
+ BERLIN_PINCTRL_FUNCTION_UNKNOW),
+ BERLIN_PINCTRL_GROUP("GSM4", 0x40, 0x2, 0x08,
+ BERLIN_PINCTRL_FUNCTION_UNKNOW),
+ BERLIN_PINCTRL_GROUP("GSM5", 0x40, 0x2, 0x0a,
+ BERLIN_PINCTRL_FUNCTION_UNKNOW),
+ BERLIN_PINCTRL_GROUP("GSM6", 0x40, 0x2, 0x0c,
+ BERLIN_PINCTRL_FUNCTION_UNKNOW),
+ BERLIN_PINCTRL_GROUP("GSM7", 0x40, 0x1, 0x0e,
+ BERLIN_PINCTRL_FUNCTION_UNKNOW),
+ BERLIN_PINCTRL_GROUP("GSM8", 0x40, 0x1, 0x0f,
+ BERLIN_PINCTRL_FUNCTION_UNKNOW),
+ BERLIN_PINCTRL_GROUP("GSM9", 0x40, 0x1, 0x10,
+ BERLIN_PINCTRL_FUNCTION_UNKNOW),
+ BERLIN_PINCTRL_GROUP("GSM10", 0x40, 0x1, 0x11,
+ BERLIN_PINCTRL_FUNCTION_UNKNOW),
+ BERLIN_PINCTRL_GROUP("GSM11", 0x40, 0x1, 0x12,
+ BERLIN_PINCTRL_FUNCTION_UNKNOW),
+};
+
+static const struct berlin_pinctrl_desc berlin2cd_soc_pinctrl_data = {
+ .groups = berlin2cd_soc_pinctrl_groups,
+ .ngroups = ARRAY_SIZE(berlin2cd_soc_pinctrl_groups),
+};
+
+static const struct berlin_pinctrl_desc berlin2cd_sysmgr_pinctrl_data = {
+ .groups = berlin2cd_sysmgr_pinctrl_groups,
+ .ngroups = ARRAY_SIZE(berlin2cd_sysmgr_pinctrl_groups),
+};
+
+static const struct of_device_id berlin2cd_pinctrl_match[] = {
+ {
+ .compatible = "marvell,berlin2cd-soc-pinctrl",
+ .data = &berlin2cd_soc_pinctrl_data
+ },
+ {
+ .compatible = "marvell,berlin2cd-sysmgr-pinctrl",
+ .data = &berlin2cd_sysmgr_pinctrl_data
+ },
+ {}
+};
+MODULE_DEVICE_TABLE(of, berlin2cd_pinctrl_match);
+
+static int berlin2cd_pinctrl_probe(struct platform_device *pdev)
+{
+ const struct of_device_id
+ *device = of_match_device(berlin2cd_pinctrl_match, &pdev->dev);
+
+ return berlin_pinctrl_probe(pdev, device->data);
+}
+
+static struct platform_driver berlin2cd_pinctrl_driver = {
+ .probe = berlin2cd_pinctrl_probe,
+ .driver = {
+ .name = "berlin-bg2cd-pinctrl",
+ .owner = THIS_MODULE,
+ .of_match_table = berlin2cd_pinctrl_match,
+ },
+};
+module_platform_driver(berlin2cd_pinctrl_driver);
+
+MODULE_AUTHOR("Antoine Ténart <[email protected]>");
+MODULE_DESCRIPTION("Marvell Berlin BG2CD pinctrl driver");
+MODULE_LICENSE("GPL");
--
1.8.3.2

2014-04-23 15:54:43

by Antoine Tenart

[permalink] [raw]
Subject: [PATCH v2 7/7] ARM: dts: berlin: add the pinctrl node and muxing setup for uarts

The uart0 pinmux configuration is in the dtsi because uart0 will always
use uart0-pmux to work, no other possibility. Same thing for uart1.

Signed-off-by: Antoine Ténart <[email protected]>
---
arch/arm/boot/dts/berlin2.dtsi | 24 ++++++++++++++++++++++++
arch/arm/boot/dts/berlin2cd.dtsi | 17 +++++++++++++++++
arch/arm/boot/dts/berlin2q.dtsi | 24 ++++++++++++++++++++++++
3 files changed, 65 insertions(+)

diff --git a/arch/arm/boot/dts/berlin2.dtsi b/arch/arm/boot/dts/berlin2.dtsi
index 56a1af2f1052..9a13891c38a3 100644
--- a/arch/arm/boot/dts/berlin2.dtsi
+++ b/arch/arm/boot/dts/berlin2.dtsi
@@ -176,6 +176,11 @@
};
};

+ soc_pinctrl: pin-controller@ea0000 {
+ compatible = "marvell,berlin2-soc-pinctrl";
+ reg = <0xea0000 0x4c>;
+ };
+
apb@fc0000 {
compatible = "simple-bus";
#address-cells = <1>;
@@ -184,6 +189,21 @@
ranges = <0 0xfc0000 0x10000>;
interrupt-parent = <&sic>;

+ sm_pinctrl: pin-controller@0000 {
+ compatible = "marvell,berlin2-sysmgr-pinctrl";
+ reg = <0x0000 0x44>;
+
+ uart0_pmux: uart0-pmux {
+ marvell,groups = "GSM4";
+ marvell,function = "uart0";
+ };
+
+ uart1_pmux: uart1-pmux {
+ marvell,groups = "GSM5";
+ marvell,function = "uart1";
+ };
+ };
+
uart0: serial@9000 {
compatible = "snps,dw-apb-uart";
reg = <0x9000 0x100>;
@@ -191,6 +211,8 @@
reg-io-width = <1>;
interrupts = <8>;
clocks = <&smclk>;
+ pinctrl-0 = <&uart0_pmux>;
+ pinctrl-names = "default";
status = "disabled";
};

@@ -201,6 +223,8 @@
reg-io-width = <1>;
interrupts = <9>;
clocks = <&smclk>;
+ pinctrl-0 = <&uart1_pmux>;
+ pinctrl-names = "default";
status = "disabled";
};

diff --git a/arch/arm/boot/dts/berlin2cd.dtsi b/arch/arm/boot/dts/berlin2cd.dtsi
index 094968c27533..a802d3fe5da6 100644
--- a/arch/arm/boot/dts/berlin2cd.dtsi
+++ b/arch/arm/boot/dts/berlin2cd.dtsi
@@ -169,6 +169,11 @@
};
};

+ soc_pinctrl: pin-controller@ae0000 {
+ compatible = "marvell,berlin2cd-soc-pinctrl";
+ reg = <0xea0000 0x4c>;
+ };
+
apb@fc0000 {
compatible = "simple-bus";
#address-cells = <1>;
@@ -177,6 +182,16 @@
ranges = <0 0xfc0000 0x10000>;
interrupt-parent = <&sic>;

+ sm_pinctrl: pin-controller@0000 {
+ compatible = "marvell,berlin2cd-sysmgr-pinctrl";
+ reg = <0x0000 0x44>;
+
+ uart0_pmux: uart0-pmux {
+ marvell,groups = "G6";
+ marvell,function = "uart0";
+ };
+ };
+
uart0: serial@9000 {
compatible = "snps,dw-apb-uart";
reg = <0x9000 0x100>;
@@ -184,6 +199,8 @@
reg-io-width = <1>;
interrupts = <8>;
clocks = <&smclk>;
+ pinctrl-0 = <&uart0_pmux>;
+ pinctrl-names = "default";
status = "disabled";
};

diff --git a/arch/arm/boot/dts/berlin2q.dtsi b/arch/arm/boot/dts/berlin2q.dtsi
index 07452a7483fa..734debbf072f 100644
--- a/arch/arm/boot/dts/berlin2q.dtsi
+++ b/arch/arm/boot/dts/berlin2q.dtsi
@@ -183,6 +183,11 @@
};
};

+ soc_pinctrl: pin-controller@ea0000 {
+ compatible = "marvell,berlin2q-soc-pinctrl";
+ reg = <0xea0000 0x4c>;
+ };
+
apb@fc0000 {
compatible = "simple-bus";
#address-cells = <1>;
@@ -198,6 +203,8 @@
interrupts = <8>;
clocks = <&smclk>;
reg-shift = <2>;
+ pinctrl-0 = <&uart0_pmux>;
+ pinctrl-names = "default";
status = "disabled";
};

@@ -208,9 +215,26 @@
interrupts = <9>;
clocks = <&smclk>;
reg-shift = <2>;
+ pinctrl-0 = <&uart1_pmux>;
+ pinctrl-names = "default";
status = "disabled";
};

+ sm_pinctrl: pin-controller@d000 {
+ compatible = "marvell,berlin2q-sysmgr-pinctrl";
+ reg = <0xd000 0x44>;
+
+ uart0_pmux: uart0-pmux {
+ marvell,groups = "GSM12";
+ marvell,function = "uart0";
+ };
+
+ uart1_pmux: uart1-pmux {
+ marvell,groups = "GSM14";
+ marvell,function = "uart1";
+ };
+ };
+
sic: interrupt-controller@e000 {
compatible = "snps,dw-apb-ictl";
reg = <0xe000 0x30>;
--
1.8.3.2

2014-04-23 15:56:47

by Antoine Tenart

[permalink] [raw]
Subject: [PATCH v2 2/7] pinctrl: berlin: add the BG2Q pinctrl driver

Add the pin-controller driver for the Berlin BG2Q SoC, with definition
of its groups and functions. This uses the core Berlin pinctrl driver.

Signed-off-by: Antoine Ténart <[email protected]>
---
drivers/pinctrl/berlin/Kconfig | 4 +
drivers/pinctrl/berlin/Makefile | 1 +
drivers/pinctrl/berlin/berlin-bg2q.c | 413 +++++++++++++++++++++++++++++++++++
3 files changed, 418 insertions(+)
create mode 100644 drivers/pinctrl/berlin/berlin-bg2q.c

diff --git a/drivers/pinctrl/berlin/Kconfig b/drivers/pinctrl/berlin/Kconfig
index df843e01a001..58ecfd797dd8 100644
--- a/drivers/pinctrl/berlin/Kconfig
+++ b/drivers/pinctrl/berlin/Kconfig
@@ -4,4 +4,8 @@ config PINCTRL_BERLIN
bool
select PINMUX

+config PINCTRL_BERLIN_BG2Q
+ bool
+ select PINCTRL_BERLIN
+
endif
diff --git a/drivers/pinctrl/berlin/Makefile b/drivers/pinctrl/berlin/Makefile
index 251a2b4e1057..1866b1f2d1cf 100644
--- a/drivers/pinctrl/berlin/Makefile
+++ b/drivers/pinctrl/berlin/Makefile
@@ -1 +1,2 @@
obj-$(CONFIG_PINCTRL_BERLIN) += berlin.o
+obj-$(CONFIG_PINCTRL_BERLIN_BG2Q) += berlin-bg2q.o
diff --git a/drivers/pinctrl/berlin/berlin-bg2q.c b/drivers/pinctrl/berlin/berlin-bg2q.c
new file mode 100644
index 000000000000..de5a6434be86
--- /dev/null
+++ b/drivers/pinctrl/berlin/berlin-bg2q.c
@@ -0,0 +1,413 @@
+/*
+ * Marvell Berlin BG2Q pinctrl driver
+ *
+ * Copyright (C) 2014 Marvell Technology Group Ltd.
+ *
+ * Antoine Ténart <[email protected]>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+
+#include "berlin.h"
+
+static const struct berlin_desc_group berlin2q_soc_pinctrl_groups[] = {
+ /* G */
+ BERLIN_PINCTRL_GROUP("G0", 0x18, 0x3, 0x00,
+ BERLIN_PINCTRL_FUNCTION(0x0, "nand"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "emmc"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "gpio")),
+ BERLIN_PINCTRL_GROUP("G1", 0x18, 0x3, 0x03,
+ BERLIN_PINCTRL_FUNCTION(0x0, "nand"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "gpio")),
+ BERLIN_PINCTRL_GROUP("G2", 0x18, 0x3, 0x06,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "arc"),
+ BERLIN_PINCTRL_FUNCTION(0x3, "lvds_vsync")),
+ BERLIN_PINCTRL_GROUP("G3", 0x18, 0x3, 0x09,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "i2s2"),
+ BERLIN_PINCTRL_FUNCTION(0x3, "lvds_lrid")),
+ BERLIN_PINCTRL_GROUP("G4", 0x18, 0x3, 0x0c,
+ BERLIN_PINCTRL_FUNCTION(0x0, "pll"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "sd0"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "rgmii"),
+ BERLIN_PINCTRL_FUNCTION(0x3, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x5, "sata_dbg"),
+ BERLIN_PINCTRL_FUNCTION(0x6, "usb0_dbg"),
+ BERLIN_PINCTRL_FUNCTION(0x7, "usb1_dbg")),
+ BERLIN_PINCTRL_GROUP("G5", 0x18, 0x3, 0x0f,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "sd0"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "rgmii"),
+ BERLIN_PINCTRL_FUNCTION(0x5, "sata_dbg"),
+ BERLIN_PINCTRL_FUNCTION(0x6, "usb0_dbg"),
+ BERLIN_PINCTRL_FUNCTION(0x7, "usb1_dbg")),
+ BERLIN_PINCTRL_GROUP("G6", 0x18, 0x3, 0x12,
+ BERLIN_PINCTRL_FUNCTION(0x0, "soc"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "tw0"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "gpio")),
+ BERLIN_PINCTRL_GROUP("G7", 0x18, 0x3, 0x15,
+ BERLIN_PINCTRL_FUNCTION(0x0, "soc"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "tw1"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x3, "eddc")),
+ BERLIN_PINCTRL_GROUP("G8", 0x18, 0x3, 0x18,
+ BERLIN_PINCTRL_FUNCTION(0x0, "spi1"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "gpio")),
+ BERLIN_PINCTRL_GROUP("G9", 0x18, 0x3, 0x1b,
+ BERLIN_PINCTRL_FUNCTION(0x0, "spi1"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x5, "sata")),
+ BERLIN_PINCTRL_GROUP("G10", 0x1c, 0x3, 0x00,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "spi1"),
+ BERLIN_PINCTRL_FUNCTION(0x3, "i2s0"),
+ BERLIN_PINCTRL_FUNCTION(0x4, "pwm"),
+ BERLIN_PINCTRL_FUNCTION(0x5, "sata")),
+ BERLIN_PINCTRL_GROUP("G11", 0x1c, 0x3, 0x03,
+ BERLIN_PINCTRL_FUNCTION(0x0, "soc"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "spi1"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x3, "i2s1"),
+ BERLIN_PINCTRL_FUNCTION(0x4, "pwm"),
+ BERLIN_PINCTRL_FUNCTION(0x5, "sata")),
+ BERLIN_PINCTRL_GROUP("G12", 0x1c, 0x3, 0x06,
+ BERLIN_PINCTRL_FUNCTION(0x0, "agc"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "gpio")),
+ BERLIN_PINCTRL_GROUP("G13", 0x1c, 0x3, 0x09,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "sts1"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "rgmii"),
+ BERLIN_PINCTRL_FUNCTION(0x6, "usb0_dbg"),
+ BERLIN_PINCTRL_FUNCTION(0x7, "usb1_dbg")),
+ BERLIN_PINCTRL_GROUP("G14", 0x1c, 0x3, 0x0c,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "sts0"),
+ BERLIN_PINCTRL_FUNCTION(0x4, "sts1"),
+ BERLIN_PINCTRL_FUNCTION(0x6, "usb0_dbg"),
+ BERLIN_PINCTRL_FUNCTION(0x7, "usb1_dbg")),
+ BERLIN_PINCTRL_GROUP("G15", 0x1c, 0x3, 0x0f,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "sts0"),
+ BERLIN_PINCTRL_FUNCTION(0x4, "sts1"),
+ BERLIN_PINCTRL_FUNCTION(0x5, "vdac"),
+ BERLIN_PINCTRL_FUNCTION(0x6, "usb0_dbg"),
+ BERLIN_PINCTRL_FUNCTION(0x7, "usb1_dbg")),
+ BERLIN_PINCTRL_GROUP("G16", 0x1c, 0x3, 0x12,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "sts0"),
+ BERLIN_PINCTRL_FUNCTION(0x4, "sts1"),
+ BERLIN_PINCTRL_FUNCTION(0x5, "osco"),
+ BERLIN_PINCTRL_FUNCTION(0x6, "usb0_dbg"),
+ BERLIN_PINCTRL_FUNCTION(0x7, "usb1_dbg")),
+ BERLIN_PINCTRL_GROUP("G17", 0x1c, 0x3, 0x15,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "rgmii"),
+ BERLIN_PINCTRL_FUNCTION(0x3, "spdif"),
+ BERLIN_PINCTRL_FUNCTION(0x4, "sts1"),
+ BERLIN_PINCTRL_FUNCTION(0x6, "usb0_dbg"),
+ BERLIN_PINCTRL_FUNCTION(0x7, "usb1_dbg")),
+ BERLIN_PINCTRL_GROUP("G18", 0x1c, 0x3, 0x18,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "rgmii"),
+ BERLIN_PINCTRL_FUNCTION(0x3, "i2s2"),
+ BERLIN_PINCTRL_FUNCTION(0x4, "sts1")),
+ BERLIN_PINCTRL_GROUP("G19", 0x1c, 0x3, 0x1b,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "rgmii"),
+ BERLIN_PINCTRL_FUNCTION(0x3, "i2s3"),
+ BERLIN_PINCTRL_FUNCTION(0x4, "sts1"),
+ BERLIN_PINCTRL_FUNCTION(0x5, "osco")),
+ BERLIN_PINCTRL_GROUP("G20", 0x20, 0x3, 0x00,
+ BERLIN_PINCTRL_FUNCTION(0x0, "cam"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x3, "demod"),
+ /*
+ * Mode 0x4 mux usb2_dbg *and* usb3_dbg:
+ * add two functions so it can be used with other groups
+ * within the same subnode in the device tree
+ */
+ BERLIN_PINCTRL_FUNCTION(0x4, "usb2_dbg"),
+ BERLIN_PINCTRL_FUNCTION(0x4, "usb3_dbg")),
+ BERLIN_PINCTRL_GROUP("G21", 0x20, 0x3, 0x03,
+ BERLIN_PINCTRL_FUNCTION(0x0, "cam"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "sts2"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x3, "demod")),
+ BERLIN_PINCTRL_GROUP("G22", 0x20, 0x3, 0x06,
+ BERLIN_PINCTRL_FUNCTION(0x0, "cam"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "gpio")),
+ BERLIN_PINCTRL_GROUP("G23", 0x20, 0x3, 0x09,
+ BERLIN_PINCTRL_FUNCTION(0x0, "cam"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x3, "avif"),
+ BERLIN_PINCTRL_FUNCTION(0x4, "usb2_dbg")),
+ BERLIN_PINCTRL_GROUP("G24", 0x20, 0x3, 0x0c,
+ BERLIN_PINCTRL_FUNCTION(0x0, "cam"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x3, "demod"),
+ BERLIN_PINCTRL_FUNCTION(0x4, "usb2_dbg")),
+ BERLIN_PINCTRL_GROUP("G25", 0x20, 0x3, 0x0f,
+ BERLIN_PINCTRL_FUNCTION(0x0, "cam"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "vga"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x3, "avif"),
+ BERLIN_PINCTRL_FUNCTION(0x4, "usb2_dbg")),
+ BERLIN_PINCTRL_GROUP("G26", 0x20, 0x3, 0x12,
+ BERLIN_PINCTRL_FUNCTION(0x0, "cam"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "lvds"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "gpio")),
+ BERLIN_PINCTRL_GROUP("G27", 0x20, 0x3, 0x15,
+ BERLIN_PINCTRL_FUNCTION(0x0, "cam"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "agc"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "gpio")),
+ BERLIN_PINCTRL_GROUP("G28", 0x20, 0x3, 0x18,
+ BERLIN_PINCTRL_FUNCTION(0x0, "cam"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x3, "avif"),
+ BERLIN_PINCTRL_FUNCTION(0x4, "usb2_dbg")),
+ BERLIN_PINCTRL_GROUP("G29", 0x20, 0x3, 0x1b,
+ BERLIN_PINCTRL_FUNCTION(0x0, "cam"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "scrd0"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "gpio")),
+ BERLIN_PINCTRL_GROUP("G30", 0x24, 0x3, 0x00,
+ BERLIN_PINCTRL_FUNCTION(0x0, "cam"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "scrd1"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "gpio")),
+ BERLIN_PINCTRL_GROUP("G31", 0x24, 0x3, 0x03,
+ BERLIN_PINCTRL_FUNCTION(0x0, "cam"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "sd1"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "gpio")),
+ BERLIN_PINCTRL_GROUP("G32", 0x24, 0x3, 0x06,
+ BERLIN_PINCTRL_FUNCTION(0x0, "cam"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "sd1"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "gpio")),
+ /* GAV */
+ BERLIN_PINCTRL_GROUP("GAV0", 0x24, 0x3, 0x09,
+ BERLIN_PINCTRL_FUNCTION(0x0, "avio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "dvio"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "fp"),
+ BERLIN_PINCTRL_FUNCTION(0x4, "lvds")),
+ BERLIN_PINCTRL_GROUP("GAV1", 0x24, 0x3, 0x0c,
+ BERLIN_PINCTRL_FUNCTION(0x0, "avio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "dvio"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "fp"),
+ BERLIN_PINCTRL_FUNCTION(0x4, "vga")),
+ BERLIN_PINCTRL_GROUP("GAV2", 0x24, 0x3, 0x0f,
+ BERLIN_PINCTRL_FUNCTION(0x0, "avio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "dvio"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "fp"),
+ BERLIN_PINCTRL_FUNCTION(0x3, "i2s3"),
+ BERLIN_PINCTRL_FUNCTION(0x4, "pdm"),
+ BERLIN_PINCTRL_FUNCTION(0x6, "adac")),
+ BERLIN_PINCTRL_GROUP("GAV3", 0x24, 0x3, 0x12,
+ BERLIN_PINCTRL_FUNCTION(0x0, "avio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "dvio"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "fp"),
+ BERLIN_PINCTRL_FUNCTION(0x3, "i2s3"),
+ BERLIN_PINCTRL_FUNCTION(0x6, "adac")),
+ BERLIN_PINCTRL_GROUP("GAV4", 0x24, 0x3, 0x15,
+ BERLIN_PINCTRL_FUNCTION(0x0, "avio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "dvio"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "fp"),
+ BERLIN_PINCTRL_FUNCTION(0x4, "i2s1"),
+ BERLIN_PINCTRL_FUNCTION(0x6, "adac")),
+ BERLIN_PINCTRL_GROUP("GAV5", 0x24, 0x3, 0x18,
+ BERLIN_PINCTRL_FUNCTION(0x0, "avio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "dvio"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "fp"),
+ BERLIN_PINCTRL_FUNCTION(0x4, "spdif")),
+ BERLIN_PINCTRL_GROUP("GAV6", 0x24, 0x3, 0x1b,
+ BERLIN_PINCTRL_FUNCTION(0x0, "avio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "dvio"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "fp"),
+ BERLIN_PINCTRL_FUNCTION(0x4, "i2s2")),
+ BERLIN_PINCTRL_GROUP("GAV7", 0x28, 0x3, 0x00,
+ BERLIN_PINCTRL_FUNCTION(0x0, "avio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "dvio"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "fp"),
+ BERLIN_PINCTRL_FUNCTION(0x4, "i2s3")),
+ BERLIN_PINCTRL_GROUP("GAV8", 0x28, 0x3, 0x03,
+ BERLIN_PINCTRL_FUNCTION(0x0, "avio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "dv0"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "fp"),
+ BERLIN_PINCTRL_FUNCTION(0x4, "pwm")),
+ BERLIN_PINCTRL_GROUP("GAV9", 0x28, 0x3, 0x06,
+ BERLIN_PINCTRL_FUNCTION(0x0, "avio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "dv0"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "fp"),
+ BERLIN_PINCTRL_FUNCTION(0x4, "pwm")),
+ BERLIN_PINCTRL_GROUP("GAV10", 0x28, 0x3, 0x09,
+ BERLIN_PINCTRL_FUNCTION(0x0, "avio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "dv0"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "fp"),
+ BERLIN_PINCTRL_FUNCTION(0x4, "agc")),
+ BERLIN_PINCTRL_GROUP("GAV11", 0x28, 0x3, 0x0c,
+ BERLIN_PINCTRL_FUNCTION(0x0, "avio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "dv0"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "fp"),
+ BERLIN_PINCTRL_FUNCTION(0x3, "i2s0"),
+ BERLIN_PINCTRL_FUNCTION(0x4, "avio_pwm"),
+ BERLIN_PINCTRL_FUNCTION(0x5, "vclki")),
+ BERLIN_PINCTRL_GROUP("GAV12", 0x28, 0x3, 0x0f,
+ BERLIN_PINCTRL_FUNCTION(0x0, "avio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "i2s2"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "i2s1")),
+ BERLIN_PINCTRL_GROUP("GAV13", 0x28, 0x3, 0x12,
+ BERLIN_PINCTRL_FUNCTION(0x0, "avio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "i2s2")),
+ BERLIN_PINCTRL_GROUP("GAV14", 0x28, 0x3, 0x15,
+ BERLIN_PINCTRL_FUNCTION(0x0, "avio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "i2s2"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "i2s1")),
+ BERLIN_PINCTRL_GROUP("GAV15", 0x28, 0x3, 0x18,
+ BERLIN_PINCTRL_FUNCTION(0x0, "avio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "i2s1"),
+ BERLIN_PINCTRL_FUNCTION(0x6, "dac_dbg")),
+ BERLIN_PINCTRL_GROUP("GAV16", 0x28, 0x3, 0x1b,
+ BERLIN_PINCTRL_FUNCTION(0x0, "avio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "i2s0"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "i2s1"),
+ BERLIN_PINCTRL_FUNCTION(0x4, "i2s3"),
+ BERLIN_PINCTRL_FUNCTION(0x5, "pdm"),
+ BERLIN_PINCTRL_FUNCTION(0x6, "dac_dbg")),
+ BERLIN_PINCTRL_GROUP("GAV17", 0x2c, 0x3, 0x00,
+ BERLIN_PINCTRL_FUNCTION(0x0, "avio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "i2s0"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "i2s1"),
+ BERLIN_PINCTRL_FUNCTION(0x3, "pwm"),
+ BERLIN_PINCTRL_FUNCTION(0x4, "i2s3"),
+ BERLIN_PINCTRL_FUNCTION(0x5, "pdm"),
+ BERLIN_PINCTRL_FUNCTION(0x6, "dac_dbg")),
+ BERLIN_PINCTRL_GROUP("GAV18", 0x2c, 0x3, 0x03,
+ BERLIN_PINCTRL_FUNCTION(0x0, "avio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "spdif"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "arc")),
+ BERLIN_PINCTRL_GROUP("GAV19", 0x2c, 0x3, 0x06,
+ BERLIN_PINCTRL_FUNCTION(0x0, "avio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "spdif"),
+ BERLIN_PINCTRL_FUNCTION(0x4, "i2s3"),
+ BERLIN_PINCTRL_FUNCTION(0x5, "pdm")),
+};
+
+static const struct berlin_desc_group berlin2q_sysmgr_pinctrl_groups[] = {
+ /* GSM */
+ BERLIN_PINCTRL_GROUP("GSM0", 0x40, 0x2, 0x00,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "spi2"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "eth1")),
+ BERLIN_PINCTRL_GROUP("GSM1", 0x40, 0x2, 0x02,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "spi2"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "eth1")),
+ BERLIN_PINCTRL_GROUP("GSM2", 0x40, 0x2, 0x04,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "spi2"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "eddc")),
+ BERLIN_PINCTRL_GROUP("GSM3", 0x40, 0x2, 0x06,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "spi2"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "eddc")),
+ BERLIN_PINCTRL_GROUP("GSM4", 0x40, 0x1, 0x08,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "hdmi")),
+ BERLIN_PINCTRL_GROUP("GSM5", 0x40, 0x1, 0x09,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "hdmi")),
+ BERLIN_PINCTRL_GROUP("GSM6", 0x40, 0x1, 0x0a,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "hdmi")),
+ BERLIN_PINCTRL_GROUP("GSM7", 0x40, 0x1, 0x0b,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "hdmi")),
+ BERLIN_PINCTRL_GROUP("GSM8", 0x40, 0x1, 0x0c,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "hdmi")),
+ BERLIN_PINCTRL_GROUP("GSM9", 0x40, 0x1, 0x0d,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "hdmi")),
+ BERLIN_PINCTRL_GROUP("GSM10", 0x40, 0x1, 0x0e,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "led")),
+ BERLIN_PINCTRL_GROUP("GSM11", 0x40, 0x1, 0x0f,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "led")),
+ BERLIN_PINCTRL_GROUP("GSM12", 0x40, 0x2, 0x10,
+ BERLIN_PINCTRL_FUNCTION(0x0, "uart0"), /* RX/TX */
+ BERLIN_PINCTRL_FUNCTION(0x1, "irda0"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "gpio")),
+ BERLIN_PINCTRL_GROUP("GSM13", 0x40, 0x2, 0x12,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "uart0"), /* CTS/RDS */
+ BERLIN_PINCTRL_FUNCTION(0x2, "uart1"), /* RX/TX */
+ BERLIN_PINCTRL_FUNCTION(0x3, "tw2")),
+ BERLIN_PINCTRL_GROUP("GSM14", 0x40, 0x2, 0x14,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "uart1"), /* RX/TX */
+ BERLIN_PINCTRL_FUNCTION(0x2, "irda1"),
+ BERLIN_PINCTRL_FUNCTION(0x3, "tw3")),
+ BERLIN_PINCTRL_GROUP("GSM15", 0x40, 0x2, 0x16,
+ BERLIN_PINCTRL_FUNCTION(0x0, "pwr"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "led"),
+ BERLIN_PINCTRL_FUNCTION(0x2, "gpio")),
+ BERLIN_PINCTRL_GROUP("GSM16", 0x40, 0x1, 0x18,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "eddc")),
+ BERLIN_PINCTRL_GROUP("GSM17", 0x40, 0x1, 0x19,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "eddc")),
+ BERLIN_PINCTRL_GROUP("GSM18", 0x40, 0x1, 0x1a,
+ BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
+ BERLIN_PINCTRL_FUNCTION(0x1, "eddc")),
+};
+
+static const struct berlin_pinctrl_desc berlin2q_soc_pinctrl_data = {
+ .groups = berlin2q_soc_pinctrl_groups,
+ .ngroups = ARRAY_SIZE(berlin2q_soc_pinctrl_groups),
+};
+
+static const struct berlin_pinctrl_desc berlin2q_sysmgr_pinctrl_data = {
+ .groups = berlin2q_sysmgr_pinctrl_groups,
+ .ngroups = ARRAY_SIZE(berlin2q_sysmgr_pinctrl_groups),
+};
+
+static const struct of_device_id berlin2q_pinctrl_match[] = {
+ {
+ .compatible = "marvell,berlin2q-soc-pinctrl",
+ .data = &berlin2q_soc_pinctrl_data,
+ },
+ {
+ .compatible = "marvell,berlin2q-sysmgr-pinctrl",
+ .data = &berlin2q_sysmgr_pinctrl_data,
+ },
+ {}
+};
+MODULE_DEVICE_TABLE(of, berlin2q_pinctrl_match);
+
+static int berlin2q_pinctrl_probe(struct platform_device *pdev)
+{
+ const struct of_device_id
+ *device = of_match_device(berlin2q_pinctrl_match, &pdev->dev);
+
+ return berlin_pinctrl_probe(pdev, device->data);
+}
+
+static struct platform_driver berlin2q_pinctrl_driver = {
+ .probe = berlin2q_pinctrl_probe,
+ .driver = {
+ .name = "berlin-bg2q-pinctrl",
+ .owner = THIS_MODULE,
+ .of_match_table = berlin2q_pinctrl_match,
+ },
+};
+module_platform_driver(berlin2q_pinctrl_driver);
+
+MODULE_AUTHOR("Antoine Ténart <[email protected]>");
+MODULE_DESCRIPTION("Marvell Berlin BG2Q pinctrl driver");
+MODULE_LICENSE("GPL");
--
1.8.3.2

2014-04-23 16:01:08

by Antoine Tenart

[permalink] [raw]
Subject: [PATCH v2 1/7] pinctrl: berlin: add the core pinctrl driver for Marvell Berlin SoCs

The Marvell Berlin boards have a group based pinmuxing mechanism. This
adds the core driver support. We actually do not need any information
about the pins here and only have the definition of the groups.

Let's take the example of the uart0 pinmuxing on the BG2Q. Balls BK4 and
BH6 are muxed to respectively UART0 RX and TX if the group GSM12 is set
to mode 0:

Group Modes Offset Base Offset LSB Bit Width
GSM12 3 sm_base 0x40 0x10 0x2

Ball Group Mode 0 Mode 1 Mode 2
BK4 GSM12 UART0_RX IrDA0_RX GPIO9
BH6 GSM12 UART0_TX IrDA0_TX GPIO10

So in order to configure BK4 -> UART0_TX and BH6 -> UART0_RX, we need
to set (sm_base + 0x40 + 0x10) &= ff3fffff.

Signed-off-by: Antoine Ténart <[email protected]>
---
drivers/pinctrl/Kconfig | 1 +
drivers/pinctrl/Makefile | 1 +
drivers/pinctrl/berlin/Kconfig | 7 +
drivers/pinctrl/berlin/Makefile | 1 +
drivers/pinctrl/berlin/berlin.c | 347 ++++++++++++++++++++++++++++++++++++++++
drivers/pinctrl/berlin/berlin.h | 71 ++++++++
6 files changed, 428 insertions(+)
create mode 100644 drivers/pinctrl/berlin/Kconfig
create mode 100644 drivers/pinctrl/berlin/Makefile
create mode 100644 drivers/pinctrl/berlin/berlin.c
create mode 100644 drivers/pinctrl/berlin/berlin.h

diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index e00c02d0a094..f758fa43ab92 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -368,6 +368,7 @@ config PINCTRL_S3C64XX
depends on ARCH_S3C64XX
select PINCTRL_SAMSUNG

+source "drivers/pinctrl/berlin/Kconfig"
source "drivers/pinctrl/mvebu/Kconfig"
source "drivers/pinctrl/sh-pfc/Kconfig"
source "drivers/pinctrl/spear/Kconfig"
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index 6d3fd62b9ae8..0bd6dcb5baf9 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -68,6 +68,7 @@ obj-$(CONFIG_PINCTRL_TB10X) += pinctrl-tb10x.o
obj-$(CONFIG_PINCTRL_ST) += pinctrl-st.o
obj-$(CONFIG_PINCTRL_VF610) += pinctrl-vf610.o

+obj-$(CONFIG_ARCH_BERLIN) += berlin/
obj-$(CONFIG_PLAT_ORION) += mvebu/
obj-$(CONFIG_ARCH_SHMOBILE) += sh-pfc/
obj-$(CONFIG_SUPERH) += sh-pfc/
diff --git a/drivers/pinctrl/berlin/Kconfig b/drivers/pinctrl/berlin/Kconfig
new file mode 100644
index 000000000000..df843e01a001
--- /dev/null
+++ b/drivers/pinctrl/berlin/Kconfig
@@ -0,0 +1,7 @@
+if ARCH_BERLIN
+
+config PINCTRL_BERLIN
+ bool
+ select PINMUX
+
+endif
diff --git a/drivers/pinctrl/berlin/Makefile b/drivers/pinctrl/berlin/Makefile
new file mode 100644
index 000000000000..251a2b4e1057
--- /dev/null
+++ b/drivers/pinctrl/berlin/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_PINCTRL_BERLIN) += berlin.o
diff --git a/drivers/pinctrl/berlin/berlin.c b/drivers/pinctrl/berlin/berlin.c
new file mode 100644
index 000000000000..2f89585cde20
--- /dev/null
+++ b/drivers/pinctrl/berlin/berlin.c
@@ -0,0 +1,347 @@
+/*
+ * Marvell Berlin SoC pinctrl core driver
+ *
+ * Copyright (C) 2014 Marvell Technology Group Ltd.
+ *
+ * Antoine Ténart <[email protected]>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include "../core.h"
+#include "../pinctrl-utils.h"
+#include "berlin.h"
+
+static int berlin_pinctrl_get_group_count(struct pinctrl_dev *pctrl_dev)
+{
+ struct berlin_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev);
+
+ return pctrl->desc->ngroups;
+}
+
+static const char *berlin_pinctrl_get_group_name(struct pinctrl_dev *pctrl_dev,
+ unsigned group)
+{
+ struct berlin_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev);
+
+ return pctrl->desc->groups[group].name;
+}
+
+static int berlin_pinctrl_dt_node_to_map(struct pinctrl_dev *pctrl_dev,
+ struct device_node *node,
+ struct pinctrl_map **map,
+ unsigned *num_maps)
+{
+ struct berlin_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev);
+ struct property *prop;
+ const char *function_name, *group_name;
+ unsigned reserved_maps = 0;
+ int ret, ngroups;
+
+ *map = NULL;
+ *num_maps = 0;
+
+ ret = of_property_read_string(node, "marvell,function", &function_name);
+ if (ret) {
+ dev_err(pctrl->dev,
+ "missing 'marvell,function' property in node %s\n",
+ node->name);
+ return -EINVAL;
+ }
+
+ ngroups = of_property_count_strings(node, "marvell,groups");
+ if (ngroups < 0) {
+ dev_err(pctrl->dev,
+ "missing 'marvell,groups' property in node %s\n",
+ node->name);
+ return -EINVAL;
+ }
+
+ ret = pinctrl_utils_reserve_map(pctrl_dev, map, &reserved_maps,
+ num_maps, ngroups);
+ if (ret) {
+ dev_err(pctrl->dev, "can't reserve map: %d\n", ret);
+ return ret;
+ }
+
+ of_property_for_each_string(node, "marvell,groups", prop, group_name) {
+ ret = pinctrl_utils_add_map_mux(pctrl_dev, map, &reserved_maps,
+ num_maps, group_name,
+ function_name);
+ if (ret) {
+ dev_err(pctrl->dev, "can't add map: %d\n", ret);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static void berlin_pinctrl_dt_free_map(struct pinctrl_dev *pctrl_dev,
+ struct pinctrl_map *map,
+ unsigned nmaps)
+{
+ int i;
+
+ for (i = 0; i < nmaps; i++) {
+ if (map[i].type == PIN_MAP_TYPE_MUX_GROUP) {
+ kfree(map[i].data.mux.group);
+
+ /* a function can be applied to multiple groups */
+ if (i == 0)
+ kfree(map[i].data.mux.function);
+ }
+ }
+
+ kfree(map);
+}
+
+static const struct pinctrl_ops berlin_pinctrl_ops = {
+ .get_groups_count = &berlin_pinctrl_get_group_count,
+ .get_group_name = &berlin_pinctrl_get_group_name,
+ .dt_node_to_map = &berlin_pinctrl_dt_node_to_map,
+ .dt_free_map = &berlin_pinctrl_dt_free_map,
+};
+
+static int berlin_pinmux_get_functions_count(struct pinctrl_dev *pctrl_dev)
+{
+ struct berlin_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev);
+
+ return pctrl->nfunctions;
+}
+
+static const char *berlin_pinmux_get_function_name(struct pinctrl_dev *pctrl_dev,
+ unsigned function)
+{
+ struct berlin_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev);
+
+ return pctrl->functions[function].name;
+}
+
+static int berlin_pinmux_get_function_groups(struct pinctrl_dev *pctrl_dev,
+ unsigned function,
+ const char * const **groups,
+ unsigned * const num_groups)
+{
+ struct berlin_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev);
+
+ *groups = pctrl->functions[function].groups;
+ *num_groups = pctrl->functions[function].ngroups;
+
+ return 0;
+}
+
+static struct berlin_desc_function *
+berlin_pinctrl_find_function_by_name(struct berlin_pinctrl *pctrl,
+ const struct berlin_desc_group *group,
+ const char *fname)
+{
+ struct berlin_desc_function *function = group->functions;
+
+ while (function->name) {
+ if (!strcmp(function->name, fname))
+ return function;
+
+ function++;
+ }
+
+ return NULL;
+}
+
+static int berlin_pinmux_enable(struct pinctrl_dev *pctrl_dev,
+ unsigned function,
+ unsigned group)
+{
+ struct berlin_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev);
+ const struct berlin_desc_group *group_desc = pctrl->desc->groups + group;
+ struct berlin_pinctrl_function *func = pctrl->functions + function;
+ struct berlin_desc_function *function_desc =
+ berlin_pinctrl_find_function_by_name(pctrl, group_desc,
+ func->name);
+ unsigned long flags;
+ u32 regval;
+
+ if (!function_desc)
+ return -EINVAL;
+
+ spin_lock_irqsave(&pctrl->lock, flags);
+
+ regval = readl(pctrl->base + group_desc->offset);
+ regval &= GENMASK(group_desc->lsb + group_desc->bit_width - 1,
+ group_desc->lsb);
+ regval |= function_desc->muxval << group_desc->lsb;
+ writel_relaxed(regval, pctrl->base + group_desc->offset);
+
+ spin_unlock_irqrestore(&pctrl->lock, flags);
+
+ return 0;
+}
+
+static const struct pinmux_ops berlin_pinmux_ops = {
+ .get_functions_count = &berlin_pinmux_get_functions_count,
+ .get_function_name = &berlin_pinmux_get_function_name,
+ .get_function_groups = &berlin_pinmux_get_function_groups,
+ .enable = &berlin_pinmux_enable,
+};
+
+static int berlin_pinctrl_add_function(struct berlin_pinctrl *pctrl,
+ const char *name)
+{
+ struct berlin_pinctrl_function *function = pctrl->functions;
+
+ while (function->name) {
+ if (!strcmp(function->name, name)) {
+ function->ngroups++;
+ return -EEXIST;
+ }
+ function++;
+ }
+
+ function->name = name;
+ function->ngroups = 1;
+
+ pctrl->nfunctions++;
+
+ return 0;
+}
+
+static int berlin_pinctrl_build_state(struct platform_device *pdev)
+{
+ struct berlin_pinctrl *pctrl = platform_get_drvdata(pdev);
+ struct berlin_desc_group const *desc_group;
+ struct berlin_desc_function const *desc_function;
+ int i, max_functions = 0;
+
+ pctrl->nfunctions = 0;
+
+ for (i = 0; i < pctrl->desc->ngroups; i++) {
+ desc_group = pctrl->desc->groups + i;
+ /* compute the maxiumum number of functions a group can have */
+ max_functions += (1 << ((desc_group->bit_width) + 1));
+ }
+
+ /* we will reallocate later */
+ pctrl->functions = devm_kzalloc(&pdev->dev,
+ max_functions * sizeof(struct berlin_pinctrl_function *),
+ GFP_KERNEL);
+ if (!pctrl->functions)
+ return -ENOMEM;
+
+ /* register all functions */
+ for (i = 0; i < pctrl->desc->ngroups; i++) {
+ desc_group = pctrl->desc->groups + i;
+ desc_function = desc_group->functions;
+
+ while (desc_function->name) {
+ berlin_pinctrl_add_function(pctrl, desc_function->name);
+ desc_function++;
+ }
+ }
+
+ pctrl->functions = krealloc(pctrl->functions,
+ pctrl->nfunctions * sizeof(struct berlin_pinctrl_function *),
+ GFP_KERNEL);
+
+ /* map functions to theirs groups */
+ for (i = 0; i < pctrl->desc->ngroups; i++) {
+ desc_group = pctrl->desc->groups + i;
+ desc_function = desc_group->functions;
+
+ while (desc_function->name) {
+ struct berlin_pinctrl_function
+ *function = pctrl->functions;
+ const char **groups;
+ bool found = false;
+
+ while (function->name) {
+ if (!strcmp(desc_function->name, function->name)) {
+ found = true;
+ break;
+ }
+ function++;
+ }
+
+ if (!found)
+ return -EINVAL;
+
+ if (!function->groups) {
+ function->groups =
+ devm_kzalloc(&pdev->dev,
+ function->ngroups * sizeof(char *),
+ GFP_KERNEL);
+
+ if (!function->groups)
+ return -ENOMEM;
+ }
+
+ groups = function->groups;
+ while (*groups)
+ groups++;
+
+ *groups = desc_group->name;
+
+ desc_function++;
+ }
+ }
+
+ return 0;
+}
+
+static struct pinctrl_desc berlin_pctrl_desc = {
+ .name = "berlin-pinctrl",
+ .pctlops = &berlin_pinctrl_ops,
+ .pmxops = &berlin_pinmux_ops,
+ .owner = THIS_MODULE,
+};
+
+int berlin_pinctrl_probe(struct platform_device *pdev,
+ const struct berlin_pinctrl_desc *desc)
+{
+ struct device *dev = &pdev->dev;
+ struct berlin_pinctrl *pctrl;
+ struct resource *r;
+ int ret;
+
+ pctrl = devm_kzalloc(dev, sizeof(struct berlin_pinctrl), GFP_KERNEL);
+ if (!pctrl)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, pctrl);
+
+ spin_lock_init(&pctrl->lock);
+
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+ pctrl->base = devm_ioremap_resource(dev, r);
+ if (IS_ERR(pctrl->base))
+ return PTR_ERR(pctrl->base);
+
+ pctrl->dev = &pdev->dev;
+ pctrl->desc = desc;
+
+ ret = berlin_pinctrl_build_state(pdev);
+ if (ret) {
+ dev_err(dev, "cannot build driver state: %d\n", ret);
+ return ret;
+ }
+
+ pctrl->pctrl_dev = pinctrl_register(&berlin_pctrl_desc, dev, pctrl);
+ if (!pctrl->pctrl_dev) {
+ dev_err(dev, "failed to register pinctrl driver\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
diff --git a/drivers/pinctrl/berlin/berlin.h b/drivers/pinctrl/berlin/berlin.h
new file mode 100644
index 000000000000..4118f5532038
--- /dev/null
+++ b/drivers/pinctrl/berlin/berlin.h
@@ -0,0 +1,71 @@
+/*
+ * Marvell Berlin SoC pinctrl driver.
+ *
+ * Copyright (C) 2014 Marvell Technology Group Ltd.
+ *
+ * Antoine Ténart <[email protected]>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __PINCTRL_BERLIN_H
+#define __PINCTRL_BERLIN_H
+
+struct berlin_desc_function {
+ const char *name;
+ u8 muxval;
+};
+
+struct berlin_desc_group {
+ const char *name;
+ u8 offset;
+ u8 bit_width;
+ u8 lsb;
+ struct berlin_desc_function *functions;
+};
+
+struct berlin_pinctrl_desc {
+ const struct berlin_desc_group *groups;
+ unsigned ngroups;
+};
+
+struct berlin_pinctrl_function {
+ const char *name;
+ const char **groups;
+ unsigned ngroups;
+};
+
+struct berlin_pinctrl {
+ spinlock_t lock;
+ void __iomem *base;
+ struct device *dev;
+ const struct berlin_pinctrl_desc *desc;
+ struct berlin_pinctrl_function *functions;
+ unsigned nfunctions;
+ struct pinctrl_dev *pctrl_dev;
+};
+
+#define BERLIN_PINCTRL_GROUP(_name, _offset, _width, _lsb, ...) \
+ { \
+ .name = _name, \
+ .offset = _offset, \
+ .bit_width = _width, \
+ .lsb = _lsb, \
+ .functions = (struct berlin_desc_function[]){ \
+ __VA_ARGS__, { } }, \
+ }
+
+#define BERLIN_PINCTRL_FUNCTION(_muxval, _name) \
+ { \
+ .name = _name, \
+ .muxval = _muxval, \
+ }
+
+#define BERLIN_PINCTRL_FUNCTION_UNKNOW {}
+
+int berlin_pinctrl_probe(struct platform_device *pdev,
+ const struct berlin_pinctrl_desc *desc);
+
+#endif /* __PINCTRL_BERLIN_H */
--
1.8.3.2

2014-04-24 12:52:23

by Linus Walleij

[permalink] [raw]
Subject: Re: [PATCH v2 0/7] ARM: berlin: add pinctrl support

On Wed, Apr 23, 2014 at 5:51 PM, Antoine Ténart
<[email protected]> wrote:

> This series adds support for the Marvell Berlin pin-controller, allowing
> to configure the pin muxing from the device tree.
>
> The Berlin pin-controller support is divided into 3 drivers, each
> driving one Berlin SoC. These drivers use a Berlin common part.
>
> This series applies on top of patches introducing the Marvell Berlin
> BG2Q you can find on Sebastian's berlin/for-next branch[1] and the patch
> allowing not to define the get_group_pins() function[2].
>
> Tested on the Berlin BG2Q.

So now I need some advice from the mvebu pinctrl maintainers
(Thomas, Sebastian etc):

- Is this a totally different pin controller so that drivers/pinctrl/mvebu
can not be used?

- Really?

- OK can you help me review this thing?

- Should the base folder really be named "berlin" or is this going to
be part of a bigger family of pin controllers so a more neutral name
should be sought?

- Why do hardware engineers seek to reinvent wheels like pin
controllers, GPIO and DMA engines all the time :-/

Yours,
Linus Walleij

2014-04-24 13:09:25

by Russell King - ARM Linux

[permalink] [raw]
Subject: Re: [PATCH v2 0/7] ARM: berlin: add pinctrl support

On Thu, Apr 24, 2014 at 02:52:20PM +0200, Linus Walleij wrote:
> - Why do hardware engineers seek to reinvent wheels like pin
> controllers, GPIO and DMA engines all the time :-/

They think they have a rectangular pin cross-section which needs special
treatment to fit into the round hole in a turned-pin socket. :)

--
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
improving, and getting towards what was expected from it.

2014-04-24 13:23:36

by Sebastian Hesselbarth

[permalink] [raw]
Subject: Re: [PATCH v2 0/7] ARM: berlin: add pinctrl support

On 04/24/2014 02:52 PM, Linus Walleij wrote:
> On Wed, Apr 23, 2014 at 5:51 PM, Antoine Ténart
> <[email protected]> wrote:
>
>> This series adds support for the Marvell Berlin pin-controller, allowing
>> to configure the pin muxing from the device tree.
>>
>> The Berlin pin-controller support is divided into 3 drivers, each
>> driving one Berlin SoC. These drivers use a Berlin common part.
>>
>> This series applies on top of patches introducing the Marvell Berlin
>> BG2Q you can find on Sebastian's berlin/for-next branch[1] and the patch
>> allowing not to define the get_group_pins() function[2].
>>
>> Tested on the Berlin BG2Q.
>
> So now I need some advice from the mvebu pinctrl maintainers
> (Thomas, Sebastian etc):
>
> - Is this a totally different pin controller so that drivers/pinctrl/mvebu
> can not be used?

Unfortunately, yes. Well actually, it _can_ be seen as a subset of
the mvebu pinctrl:

- mvebu (usually) uses 4bit per mux function with 8 functions/register
- berlin uses 1-4bit per mux function with as many functions/register
as there fit in 32b.

This great feature saves _at least_ one additional address decoding!
It doesn't save registers, because they will never be synthesized, but
at least each SoC has a very different pinmux layout. *sigh*

> - Really?

Yep.

> - OK can you help me review this thing?

Sure thing!

> - Should the base folder really be named "berlin" or is this going to
> be part of a bigger family of pin controllers so a more neutral name
> should be sought?

Well, Marvell basically has two groups of SoCs, MVEBU and PXA/MMP. Don't
ask me why but sometimes they share IP, sometimes they don't.

Berlin names Marvell SoCs prefixed 88DExxxx, I *think* it may be derived
from the PXA/MMP line of SoCs. To make it more confuse,
it also got the marketing name "Armada".

> - Why do hardware engineers seek to reinvent wheels like pin
> controllers, GPIO and DMA engines all the time :-/

I guess it is: "Look what we found in our IP archives".

Honestly, I can think of making pinctrl/mvebu and pinctrl/berlin
compatible but I don't know if it is worth the pain :P

We have "custom" set/get_function() callbacks in pinctrl/mvebu
so that should fit. Each "group" of pins has a name and a bunch
of "functions", that fits too.

I need some time to think about it, but if you insist on it, I
can possibly make it work.

Sebastian

2014-04-24 13:26:26

by Thomas Petazzoni

[permalink] [raw]
Subject: Re: [PATCH v2 0/7] ARM: berlin: add pinctrl support

Dear Linus Walleij,

On Thu, 24 Apr 2014 14:52:20 +0200, Linus Walleij wrote:

> > Tested on the Berlin BG2Q.
>
> So now I need some advice from the mvebu pinctrl maintainers
> (Thomas, Sebastian etc):
>
> - Is this a totally different pin controller so that drivers/pinctrl/mvebu
> can not be used?

It is. The CPU families are completely different, made from completely
separate divisions of Marvell. Just think that they come from different
companies :-)

On the mvebu side, each pin can be independently configured to a
different function: there is a 4-bits field for each pin to configure
the function.

On the berlin side, pins are only configured in groups. You can't
independently set the functions of each pin: you can set a function to
a pre-defined set of pins.

> - Really?

Yes.

> - OK can you help me review this thing?

Sure. I believe Sebastian already had a very detailed look so he can
provide his review.

> - Should the base folder really be named "berlin" or is this going to
> be part of a bigger family of pin controllers so a more neutral name
> should be sought?

berlin is the name of the mach-<foo> directory in arch/arm, and that's
really the code name for this SoC family.

> - Why do hardware engineers seek to reinvent wheels like pin
> controllers, GPIO and DMA engines all the time :-/

I guess Russell already gave you a good answer to this question :-)

Thomas
--
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com

2014-04-25 09:13:33

by Linus Walleij

[permalink] [raw]
Subject: Re: [PATCH v2 0/7] ARM: berlin: add pinctrl support

On Wed, Apr 23, 2014 at 5:51 PM, Antoine Ténart
<[email protected]> wrote:

> This series adds support for the Marvell Berlin pin-controller, allowing
> to configure the pin muxing from the device tree.

I've looked over the patch series and there is nothing really controversial in
there, but I'm waiting for Thomas & Sebastian to provide Reviewed-by
tags.

Yours,
Linus Walleij

2014-04-26 09:18:11

by Sebastian Hesselbarth

[permalink] [raw]
Subject: Re: [PATCH v2 1/7] pinctrl: berlin: add the core pinctrl driver for Marvell Berlin SoCs

On 04/23/2014 05:51 PM, Antoine Ténart wrote:
> The Marvell Berlin boards have a group based pinmuxing mechanism. This
> adds the core driver support. We actually do not need any information
> about the pins here and only have the definition of the groups.
>
> Let's take the example of the uart0 pinmuxing on the BG2Q. Balls BK4 and
> BH6 are muxed to respectively UART0 RX and TX if the group GSM12 is set
> to mode 0:
>
> Group Modes Offset Base Offset LSB Bit Width
> GSM12 3 sm_base 0x40 0x10 0x2
>
> Ball Group Mode 0 Mode 1 Mode 2
> BK4 GSM12 UART0_RX IrDA0_RX GPIO9
> BH6 GSM12 UART0_TX IrDA0_TX GPIO10
>
> So in order to configure BK4 -> UART0_TX and BH6 -> UART0_RX, we need
> to set (sm_base + 0x40 + 0x10) &= ff3fffff.
>
> Signed-off-by: Antoine Ténart <[email protected]>

Antoine,

I only have some cosmetic nits on the pinctrl driver and one fixup for
the dts.

If you resend, feel free to add my

Acked-by: Sebastian Hesselbarth <[email protected]>

> ---
[...]
> diff --git a/drivers/pinctrl/berlin/berlin.c b/drivers/pinctrl/berlin/berlin.c
> new file mode 100644
> index 000000000000..2f89585cde20
> --- /dev/null
> +++ b/drivers/pinctrl/berlin/berlin.c
> @@ -0,0 +1,347 @@
> +/*
> + * Marvell Berlin SoC pinctrl core driver
> + *
> + * Copyright (C) 2014 Marvell Technology Group Ltd.
> + *
> + * Antoine Ténart <[email protected]>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2. This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +#include <linux/io.h>
> +#include <linux/module.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/of_device.h>
> +#include <linux/pinctrl/pinctrl.h>
> +#include <linux/pinctrl/pinmux.h>
> +#include <linux/platform_device.h>
> +#include <linux/slab.h>
> +
> +#include "../core.h"
> +#include "../pinctrl-utils.h"
> +#include "berlin.h"
> +
> +static int berlin_pinctrl_get_group_count(struct pinctrl_dev *pctrl_dev)
> +{
> + struct berlin_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev);
> +
> + return pctrl->desc->ngroups;
> +}
> +
> +static const char *berlin_pinctrl_get_group_name(struct pinctrl_dev *pctrl_dev,
> + unsigned group)
> +{
> + struct berlin_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev);
> +
> + return pctrl->desc->groups[group].name;
> +}
> +
> +static int berlin_pinctrl_dt_node_to_map(struct pinctrl_dev *pctrl_dev,
> + struct device_node *node,
> + struct pinctrl_map **map,
> + unsigned *num_maps)
> +{
> + struct berlin_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev);
> + struct property *prop;
> + const char *function_name, *group_name;
> + unsigned reserved_maps = 0;
> + int ret, ngroups;
> +
> + *map = NULL;
> + *num_maps = 0;
> +
> + ret = of_property_read_string(node, "marvell,function", &function_name);
> + if (ret) {
> + dev_err(pctrl->dev,
> + "missing 'marvell,function' property in node %s\n",
> + node->name);
> + return -EINVAL;
> + }
> +
> + ngroups = of_property_count_strings(node, "marvell,groups");
> + if (ngroups < 0) {
> + dev_err(pctrl->dev,
> + "missing 'marvell,groups' property in node %s\n",
> + node->name);
> + return -EINVAL;
> + }
> +
> + ret = pinctrl_utils_reserve_map(pctrl_dev, map, &reserved_maps,
> + num_maps, ngroups);
> + if (ret) {
> + dev_err(pctrl->dev, "can't reserve map: %d\n", ret);
> + return ret;
> + }
> +
> + of_property_for_each_string(node, "marvell,groups", prop, group_name) {
> + ret = pinctrl_utils_add_map_mux(pctrl_dev, map, &reserved_maps,
> + num_maps, group_name,
> + function_name);
> + if (ret) {
> + dev_err(pctrl->dev, "can't add map: %d\n", ret);
> + return ret;
> + }
> + }
> +
> + return 0;
> +}
> +
> +static void berlin_pinctrl_dt_free_map(struct pinctrl_dev *pctrl_dev,
> + struct pinctrl_map *map,
> + unsigned nmaps)
> +{
> + int i;
> +
> + for (i = 0; i < nmaps; i++) {
> + if (map[i].type == PIN_MAP_TYPE_MUX_GROUP) {
> + kfree(map[i].data.mux.group);
> +
> + /* a function can be applied to multiple groups */
> + if (i == 0)
> + kfree(map[i].data.mux.function);
> + }
> + }
> +
> + kfree(map);
> +}
> +
> +static const struct pinctrl_ops berlin_pinctrl_ops = {
> + .get_groups_count = &berlin_pinctrl_get_group_count,
> + .get_group_name = &berlin_pinctrl_get_group_name,
> + .dt_node_to_map = &berlin_pinctrl_dt_node_to_map,
> + .dt_free_map = &berlin_pinctrl_dt_free_map,
> +};
> +
> +static int berlin_pinmux_get_functions_count(struct pinctrl_dev *pctrl_dev)
> +{
> + struct berlin_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev);
> +
> + return pctrl->nfunctions;
> +}
> +
> +static const char *berlin_pinmux_get_function_name(struct pinctrl_dev *pctrl_dev,
> + unsigned function)
> +{
> + struct berlin_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev);
> +
> + return pctrl->functions[function].name;
> +}
> +
> +static int berlin_pinmux_get_function_groups(struct pinctrl_dev *pctrl_dev,
> + unsigned function,
> + const char * const **groups,
> + unsigned * const num_groups)
> +{
> + struct berlin_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev);
> +
> + *groups = pctrl->functions[function].groups;
> + *num_groups = pctrl->functions[function].ngroups;
> +
> + return 0;
> +}
> +
> +static struct berlin_desc_function *
> +berlin_pinctrl_find_function_by_name(struct berlin_pinctrl *pctrl,
> + const struct berlin_desc_group *group,
> + const char *fname)
> +{
> + struct berlin_desc_function *function = group->functions;
> +
> + while (function->name) {
> + if (!strcmp(function->name, fname))
> + return function;
> +
> + function++;
> + }
> +
> + return NULL;
> +}
> +
> +static int berlin_pinmux_enable(struct pinctrl_dev *pctrl_dev,
> + unsigned function,
> + unsigned group)
> +{
> + struct berlin_pinctrl *pctrl = pinctrl_dev_get_drvdata(pctrl_dev);
> + const struct berlin_desc_group *group_desc = pctrl->desc->groups + group;
> + struct berlin_pinctrl_function *func = pctrl->functions + function;
> + struct berlin_desc_function *function_desc =
> + berlin_pinctrl_find_function_by_name(pctrl, group_desc,
> + func->name);
> + unsigned long flags;
> + u32 regval;
> +
> + if (!function_desc)
> + return -EINVAL;
> +
> + spin_lock_irqsave(&pctrl->lock, flags);
> +
> + regval = readl(pctrl->base + group_desc->offset);
> + regval &= GENMASK(group_desc->lsb + group_desc->bit_width - 1,
> + group_desc->lsb);
> + regval |= function_desc->muxval << group_desc->lsb;
> + writel_relaxed(regval, pctrl->base + group_desc->offset);
> +
> + spin_unlock_irqrestore(&pctrl->lock, flags);
> +
> + return 0;
> +}
> +
> +static const struct pinmux_ops berlin_pinmux_ops = {
> + .get_functions_count = &berlin_pinmux_get_functions_count,
> + .get_function_name = &berlin_pinmux_get_function_name,
> + .get_function_groups = &berlin_pinmux_get_function_groups,
> + .enable = &berlin_pinmux_enable,
> +};
> +
> +static int berlin_pinctrl_add_function(struct berlin_pinctrl *pctrl,
> + const char *name)
> +{
> + struct berlin_pinctrl_function *function = pctrl->functions;
> +
> + while (function->name) {
> + if (!strcmp(function->name, name)) {
> + function->ngroups++;
> + return -EEXIST;
> + }
> + function++;
> + }
> +
> + function->name = name;
> + function->ngroups = 1;
> +
> + pctrl->nfunctions++;
> +
> + return 0;
> +}
> +
> +static int berlin_pinctrl_build_state(struct platform_device *pdev)
> +{
> + struct berlin_pinctrl *pctrl = platform_get_drvdata(pdev);
> + struct berlin_desc_group const *desc_group;
> + struct berlin_desc_function const *desc_function;
> + int i, max_functions = 0;
> +
> + pctrl->nfunctions = 0;
> +
> + for (i = 0; i < pctrl->desc->ngroups; i++) {
> + desc_group = pctrl->desc->groups + i;
> + /* compute the maxiumum number of functions a group can have */
> + max_functions += (1 << ((desc_group->bit_width) + 1));

nit: get rid of the outer (), they are not required.

> + }
> +
> + /* we will reallocate later */
> + pctrl->functions = devm_kzalloc(&pdev->dev,
> + max_functions * sizeof(struct berlin_pinctrl_function *),

sizeof(*pctrl->functions)?

> + GFP_KERNEL);
> + if (!pctrl->functions)
> + return -ENOMEM;
> +
> + /* register all functions */
> + for (i = 0; i < pctrl->desc->ngroups; i++) {
> + desc_group = pctrl->desc->groups + i;
> + desc_function = desc_group->functions;
> +
> + while (desc_function->name) {
> + berlin_pinctrl_add_function(pctrl, desc_function->name);
> + desc_function++;
> + }
> + }
> +
> + pctrl->functions = krealloc(pctrl->functions,
> + pctrl->nfunctions * sizeof(struct berlin_pinctrl_function *),

ditto.

> + GFP_KERNEL);
> +
> + /* map functions to theirs groups */
> + for (i = 0; i < pctrl->desc->ngroups; i++) {
> + desc_group = pctrl->desc->groups + i;
> + desc_function = desc_group->functions;
> +
> + while (desc_function->name) {
> + struct berlin_pinctrl_function
> + *function = pctrl->functions;
> + const char **groups;
> + bool found = false;
> +
> + while (function->name) {
> + if (!strcmp(desc_function->name, function->name)) {
> + found = true;
> + break;
> + }
> + function++;
> + }
> +
> + if (!found)
> + return -EINVAL;
> +
> + if (!function->groups) {
> + function->groups =
> + devm_kzalloc(&pdev->dev,
> + function->ngroups * sizeof(char *),
> + GFP_KERNEL);
> +
> + if (!function->groups)
> + return -ENOMEM;
> + }
> +
> + groups = function->groups;
> + while (*groups)
> + groups++;
> +
> + *groups = desc_group->name;
> +
> + desc_function++;
> + }
> + }
> +
> + return 0;
> +}
> +
> +static struct pinctrl_desc berlin_pctrl_desc = {
> + .name = "berlin-pinctrl",
> + .pctlops = &berlin_pinctrl_ops,
> + .pmxops = &berlin_pinmux_ops,
> + .owner = THIS_MODULE,
> +};
> +
> +int berlin_pinctrl_probe(struct platform_device *pdev,
> + const struct berlin_pinctrl_desc *desc)
> +{
> + struct device *dev = &pdev->dev;
> + struct berlin_pinctrl *pctrl;
> + struct resource *r;
> + int ret;
> +
> + pctrl = devm_kzalloc(dev, sizeof(struct berlin_pinctrl), GFP_KERNEL);

sizeof(*pctrl)

> + if (!pctrl)
> + return -ENOMEM;
> +
> + platform_set_drvdata(pdev, pctrl);
> +
> + spin_lock_init(&pctrl->lock);
> +
> + r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +

Get rid of the empty line above.

> + pctrl->base = devm_ioremap_resource(dev, r);
> + if (IS_ERR(pctrl->base))
> + return PTR_ERR(pctrl->base);
> +
> + pctrl->dev = &pdev->dev;
> + pctrl->desc = desc;
> +
> + ret = berlin_pinctrl_build_state(pdev);
> + if (ret) {
> + dev_err(dev, "cannot build driver state: %d\n", ret);
> + return ret;
> + }
> +
> + pctrl->pctrl_dev = pinctrl_register(&berlin_pctrl_desc, dev, pctrl);
> + if (!pctrl->pctrl_dev) {
> + dev_err(dev, "failed to register pinctrl driver\n");
> + return -EINVAL;
> + }
> +
> + return 0;
> +}
> diff --git a/drivers/pinctrl/berlin/berlin.h b/drivers/pinctrl/berlin/berlin.h
> new file mode 100644
> index 000000000000..4118f5532038
> --- /dev/null
> +++ b/drivers/pinctrl/berlin/berlin.h
> @@ -0,0 +1,71 @@
> +/*
> + * Marvell Berlin SoC pinctrl driver.
> + *
> + * Copyright (C) 2014 Marvell Technology Group Ltd.
> + *
> + * Antoine Ténart <[email protected]>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2. This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +#ifndef __PINCTRL_BERLIN_H
> +#define __PINCTRL_BERLIN_H
> +
> +struct berlin_desc_function {
> + const char *name;
> + u8 muxval;
> +};
> +
> +struct berlin_desc_group {
> + const char *name;
> + u8 offset;
> + u8 bit_width;
> + u8 lsb;
> + struct berlin_desc_function *functions;
> +};
> +
> +struct berlin_pinctrl_desc {
> + const struct berlin_desc_group *groups;
> + unsigned ngroups;
> +};
> +
> +struct berlin_pinctrl_function {
> + const char *name;
> + const char **groups;
> + unsigned ngroups;
> +};
> +
> +struct berlin_pinctrl {
> + spinlock_t lock;
> + void __iomem *base;
> + struct device *dev;
> + const struct berlin_pinctrl_desc *desc;
> + struct berlin_pinctrl_function *functions;
> + unsigned nfunctions;
> + struct pinctrl_dev *pctrl_dev;
> +};
> +
> +#define BERLIN_PINCTRL_GROUP(_name, _offset, _width, _lsb, ...) \
> + { \
> + .name = _name, \
> + .offset = _offset, \
> + .bit_width = _width, \
> + .lsb = _lsb, \
> + .functions = (struct berlin_desc_function[]){ \
> + __VA_ARGS__, { } }, \
> + }
> +
> +#define BERLIN_PINCTRL_FUNCTION(_muxval, _name) \
> + { \
> + .name = _name, \
> + .muxval = _muxval, \
> + }
> +
> +#define BERLIN_PINCTRL_FUNCTION_UNKNOW {}

s/UNKNOW/UNKNOWN/ and in the following 3 patches, too.

Sebastian

> +
> +int berlin_pinctrl_probe(struct platform_device *pdev,
> + const struct berlin_pinctrl_desc *desc);
> +
> +#endif /* __PINCTRL_BERLIN_H */
>

2014-04-26 09:29:55

by Sebastian Hesselbarth

[permalink] [raw]
Subject: Re: [PATCH v2 2/7] pinctrl: berlin: add the BG2Q pinctrl driver

On 04/23/2014 05:51 PM, Antoine Ténart wrote:
> Add the pin-controller driver for the Berlin BG2Q SoC, with definition
> of its groups and functions. This uses the core Berlin pinctrl driver.
>
> Signed-off-by: Antoine Ténart <[email protected]>
> ---
[...]
> diff --git a/drivers/pinctrl/berlin/berlin-bg2q.c b/drivers/pinctrl/berlin/berlin-bg2q.c
> new file mode 100644
> index 000000000000..de5a6434be86
> --- /dev/null
> +++ b/drivers/pinctrl/berlin/berlin-bg2q.c
> @@ -0,0 +1,413 @@
> +/*
> + * Marvell Berlin BG2Q pinctrl driver
> + *
> + * Copyright (C) 2014 Marvell Technology Group Ltd.
> + *
> + * Antoine Ténart <[email protected]>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2. This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +#include <linux/module.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +
> +#include "berlin.h"
> +
> +static const struct berlin_desc_group berlin2q_soc_pinctrl_groups[] = {
> + /* G */
> + BERLIN_PINCTRL_GROUP("G0", 0x18, 0x3, 0x00,
> + BERLIN_PINCTRL_FUNCTION(0x0, "nand"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "emmc"),

s/emmc/mmc ?

> + BERLIN_PINCTRL_FUNCTION(0x2, "gpio")),
> + BERLIN_PINCTRL_GROUP("G1", 0x18, 0x3, 0x03,
> + BERLIN_PINCTRL_FUNCTION(0x0, "nand"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "gpio")),
> + BERLIN_PINCTRL_GROUP("G2", 0x18, 0x3, 0x06,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "arc"),
> + BERLIN_PINCTRL_FUNCTION(0x3, "lvds_vsync")),

Shouldn't the above be:

BERLIN_PINCTRL_FUNCTION(0x3, "lvds"))), /* vsync */

> + BERLIN_PINCTRL_GROUP("G3", 0x18, 0x3, 0x09,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "i2s2"),
> + BERLIN_PINCTRL_FUNCTION(0x3, "lvds_lrid")),

ditto

> + BERLIN_PINCTRL_GROUP("G4", 0x18, 0x3, 0x0c,
> + BERLIN_PINCTRL_FUNCTION(0x0, "pll"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "sd0"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "rgmii"),
> + BERLIN_PINCTRL_FUNCTION(0x3, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x5, "sata_dbg"),
> + BERLIN_PINCTRL_FUNCTION(0x6, "usb0_dbg"),
> + BERLIN_PINCTRL_FUNCTION(0x7, "usb1_dbg")),
> + BERLIN_PINCTRL_GROUP("G5", 0x18, 0x3, 0x0f,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "sd0"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "rgmii"),
> + BERLIN_PINCTRL_FUNCTION(0x5, "sata_dbg"),
> + BERLIN_PINCTRL_FUNCTION(0x6, "usb0_dbg"),
> + BERLIN_PINCTRL_FUNCTION(0x7, "usb1_dbg")),
> + BERLIN_PINCTRL_GROUP("G6", 0x18, 0x3, 0x12,
> + BERLIN_PINCTRL_FUNCTION(0x0, "soc"),

Uhm, any idea what "soc" is for? If not, just leave it.

> + BERLIN_PINCTRL_FUNCTION(0x1, "tw0"),

s/tw/twsi/ and for the ones below.

> + BERLIN_PINCTRL_FUNCTION(0x2, "gpio")),
> + BERLIN_PINCTRL_GROUP("G7", 0x18, 0x3, 0x15,
> + BERLIN_PINCTRL_FUNCTION(0x0, "soc"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "tw1"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x3, "eddc")),
> + BERLIN_PINCTRL_GROUP("G8", 0x18, 0x3, 0x18,
> + BERLIN_PINCTRL_FUNCTION(0x0, "spi1"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "gpio")),
> + BERLIN_PINCTRL_GROUP("G9", 0x18, 0x3, 0x1b,
> + BERLIN_PINCTRL_FUNCTION(0x0, "spi1"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x5, "sata")),
> + BERLIN_PINCTRL_GROUP("G10", 0x1c, 0x3, 0x00,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "spi1"),
> + BERLIN_PINCTRL_FUNCTION(0x3, "i2s0"),
> + BERLIN_PINCTRL_FUNCTION(0x4, "pwm"),
> + BERLIN_PINCTRL_FUNCTION(0x5, "sata")),
> + BERLIN_PINCTRL_GROUP("G11", 0x1c, 0x3, 0x03,
> + BERLIN_PINCTRL_FUNCTION(0x0, "soc"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "spi1"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x3, "i2s1"),
> + BERLIN_PINCTRL_FUNCTION(0x4, "pwm"),
> + BERLIN_PINCTRL_FUNCTION(0x5, "sata")),
> + BERLIN_PINCTRL_GROUP("G12", 0x1c, 0x3, 0x06,
> + BERLIN_PINCTRL_FUNCTION(0x0, "agc"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "gpio")),
> + BERLIN_PINCTRL_GROUP("G13", 0x1c, 0x3, 0x09,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "sts1"),

Any idea what "sts" means, maybe "ts" is for Transport Stream?
No need to change it, I am just curious.

> + BERLIN_PINCTRL_FUNCTION(0x2, "rgmii"),
> + BERLIN_PINCTRL_FUNCTION(0x6, "usb0_dbg"),
> + BERLIN_PINCTRL_FUNCTION(0x7, "usb1_dbg")),
> + BERLIN_PINCTRL_GROUP("G14", 0x1c, 0x3, 0x0c,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "sts0"),
> + BERLIN_PINCTRL_FUNCTION(0x4, "sts1"),
> + BERLIN_PINCTRL_FUNCTION(0x6, "usb0_dbg"),
> + BERLIN_PINCTRL_FUNCTION(0x7, "usb1_dbg")),
> + BERLIN_PINCTRL_GROUP("G15", 0x1c, 0x3, 0x0f,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "sts0"),
> + BERLIN_PINCTRL_FUNCTION(0x4, "sts1"),
> + BERLIN_PINCTRL_FUNCTION(0x5, "vdac"),
> + BERLIN_PINCTRL_FUNCTION(0x6, "usb0_dbg"),
> + BERLIN_PINCTRL_FUNCTION(0x7, "usb1_dbg")),
> + BERLIN_PINCTRL_GROUP("G16", 0x1c, 0x3, 0x12,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "sts0"),
> + BERLIN_PINCTRL_FUNCTION(0x4, "sts1"),
> + BERLIN_PINCTRL_FUNCTION(0x5, "osco"),
> + BERLIN_PINCTRL_FUNCTION(0x6, "usb0_dbg"),
> + BERLIN_PINCTRL_FUNCTION(0x7, "usb1_dbg")),
> + BERLIN_PINCTRL_GROUP("G17", 0x1c, 0x3, 0x15,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "rgmii"),
> + BERLIN_PINCTRL_FUNCTION(0x3, "spdif"),
> + BERLIN_PINCTRL_FUNCTION(0x4, "sts1"),
> + BERLIN_PINCTRL_FUNCTION(0x6, "usb0_dbg"),
> + BERLIN_PINCTRL_FUNCTION(0x7, "usb1_dbg")),
> + BERLIN_PINCTRL_GROUP("G18", 0x1c, 0x3, 0x18,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "rgmii"),
> + BERLIN_PINCTRL_FUNCTION(0x3, "i2s2"),
> + BERLIN_PINCTRL_FUNCTION(0x4, "sts1")),
> + BERLIN_PINCTRL_GROUP("G19", 0x1c, 0x3, 0x1b,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "rgmii"),
> + BERLIN_PINCTRL_FUNCTION(0x3, "i2s3"),
> + BERLIN_PINCTRL_FUNCTION(0x4, "sts1"),
> + BERLIN_PINCTRL_FUNCTION(0x5, "osco")),
> + BERLIN_PINCTRL_GROUP("G20", 0x20, 0x3, 0x00,
> + BERLIN_PINCTRL_FUNCTION(0x0, "cam"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x3, "demod"),
> + /*
> + * Mode 0x4 mux usb2_dbg *and* usb3_dbg:
> + * add two functions so it can be used with other groups
> + * within the same subnode in the device tree
> + */
> + BERLIN_PINCTRL_FUNCTION(0x4, "usb2_dbg"),
> + BERLIN_PINCTRL_FUNCTION(0x4, "usb3_dbg")),

Nice, and I like the comment :)

> + BERLIN_PINCTRL_GROUP("G21", 0x20, 0x3, 0x03,
> + BERLIN_PINCTRL_FUNCTION(0x0, "cam"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "sts2"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x3, "demod")),
> + BERLIN_PINCTRL_GROUP("G22", 0x20, 0x3, 0x06,
> + BERLIN_PINCTRL_FUNCTION(0x0, "cam"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "gpio")),
> + BERLIN_PINCTRL_GROUP("G23", 0x20, 0x3, 0x09,
> + BERLIN_PINCTRL_FUNCTION(0x0, "cam"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x3, "avif"),
> + BERLIN_PINCTRL_FUNCTION(0x4, "usb2_dbg")),
> + BERLIN_PINCTRL_GROUP("G24", 0x20, 0x3, 0x0c,
> + BERLIN_PINCTRL_FUNCTION(0x0, "cam"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x3, "demod"),
> + BERLIN_PINCTRL_FUNCTION(0x4, "usb2_dbg")),
> + BERLIN_PINCTRL_GROUP("G25", 0x20, 0x3, 0x0f,
> + BERLIN_PINCTRL_FUNCTION(0x0, "cam"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "vga"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x3, "avif"),
> + BERLIN_PINCTRL_FUNCTION(0x4, "usb2_dbg")),
> + BERLIN_PINCTRL_GROUP("G26", 0x20, 0x3, 0x12,
> + BERLIN_PINCTRL_FUNCTION(0x0, "cam"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "lvds"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "gpio")),
> + BERLIN_PINCTRL_GROUP("G27", 0x20, 0x3, 0x15,
> + BERLIN_PINCTRL_FUNCTION(0x0, "cam"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "agc"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "gpio")),
> + BERLIN_PINCTRL_GROUP("G28", 0x20, 0x3, 0x18,
> + BERLIN_PINCTRL_FUNCTION(0x0, "cam"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x3, "avif"),
> + BERLIN_PINCTRL_FUNCTION(0x4, "usb2_dbg")),
> + BERLIN_PINCTRL_GROUP("G29", 0x20, 0x3, 0x1b,
> + BERLIN_PINCTRL_FUNCTION(0x0, "cam"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "scrd0"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "gpio")),
> + BERLIN_PINCTRL_GROUP("G30", 0x24, 0x3, 0x00,
> + BERLIN_PINCTRL_FUNCTION(0x0, "cam"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "scrd1"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "gpio")),
> + BERLIN_PINCTRL_GROUP("G31", 0x24, 0x3, 0x03,
> + BERLIN_PINCTRL_FUNCTION(0x0, "cam"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "sd1"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "gpio")),
> + BERLIN_PINCTRL_GROUP("G32", 0x24, 0x3, 0x06,
> + BERLIN_PINCTRL_FUNCTION(0x0, "cam"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "sd1"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "gpio")),
> + /* GAV */
> + BERLIN_PINCTRL_GROUP("GAV0", 0x24, 0x3, 0x09,
> + BERLIN_PINCTRL_FUNCTION(0x0, "avio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "dvio"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "fp"),
> + BERLIN_PINCTRL_FUNCTION(0x4, "lvds")),
> + BERLIN_PINCTRL_GROUP("GAV1", 0x24, 0x3, 0x0c,
> + BERLIN_PINCTRL_FUNCTION(0x0, "avio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "dvio"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "fp"),
> + BERLIN_PINCTRL_FUNCTION(0x4, "vga")),
> + BERLIN_PINCTRL_GROUP("GAV2", 0x24, 0x3, 0x0f,
> + BERLIN_PINCTRL_FUNCTION(0x0, "avio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "dvio"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "fp"),
> + BERLIN_PINCTRL_FUNCTION(0x3, "i2s3"),
> + BERLIN_PINCTRL_FUNCTION(0x4, "pdm"),
> + BERLIN_PINCTRL_FUNCTION(0x6, "adac")),
> + BERLIN_PINCTRL_GROUP("GAV3", 0x24, 0x3, 0x12,
> + BERLIN_PINCTRL_FUNCTION(0x0, "avio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "dvio"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "fp"),
> + BERLIN_PINCTRL_FUNCTION(0x3, "i2s3"),
> + BERLIN_PINCTRL_FUNCTION(0x6, "adac")),
> + BERLIN_PINCTRL_GROUP("GAV4", 0x24, 0x3, 0x15,
> + BERLIN_PINCTRL_FUNCTION(0x0, "avio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "dvio"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "fp"),
> + BERLIN_PINCTRL_FUNCTION(0x4, "i2s1"),
> + BERLIN_PINCTRL_FUNCTION(0x6, "adac")),
> + BERLIN_PINCTRL_GROUP("GAV5", 0x24, 0x3, 0x18,
> + BERLIN_PINCTRL_FUNCTION(0x0, "avio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "dvio"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "fp"),
> + BERLIN_PINCTRL_FUNCTION(0x4, "spdif")),
> + BERLIN_PINCTRL_GROUP("GAV6", 0x24, 0x3, 0x1b,
> + BERLIN_PINCTRL_FUNCTION(0x0, "avio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "dvio"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "fp"),
> + BERLIN_PINCTRL_FUNCTION(0x4, "i2s2")),
> + BERLIN_PINCTRL_GROUP("GAV7", 0x28, 0x3, 0x00,
> + BERLIN_PINCTRL_FUNCTION(0x0, "avio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "dvio"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "fp"),
> + BERLIN_PINCTRL_FUNCTION(0x4, "i2s3")),
> + BERLIN_PINCTRL_GROUP("GAV8", 0x28, 0x3, 0x03,
> + BERLIN_PINCTRL_FUNCTION(0x0, "avio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "dv0"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "fp"),
> + BERLIN_PINCTRL_FUNCTION(0x4, "pwm")),
> + BERLIN_PINCTRL_GROUP("GAV9", 0x28, 0x3, 0x06,
> + BERLIN_PINCTRL_FUNCTION(0x0, "avio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "dv0"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "fp"),
> + BERLIN_PINCTRL_FUNCTION(0x4, "pwm")),
> + BERLIN_PINCTRL_GROUP("GAV10", 0x28, 0x3, 0x09,
> + BERLIN_PINCTRL_FUNCTION(0x0, "avio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "dv0"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "fp"),
> + BERLIN_PINCTRL_FUNCTION(0x4, "agc")),
> + BERLIN_PINCTRL_GROUP("GAV11", 0x28, 0x3, 0x0c,
> + BERLIN_PINCTRL_FUNCTION(0x0, "avio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "dv0"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "fp"),
> + BERLIN_PINCTRL_FUNCTION(0x3, "i2s0"),
> + BERLIN_PINCTRL_FUNCTION(0x4, "avio_pwm"),

Is it the same "pwm" as for GAV8? If so, remove the "avio_"
prefix?

> + BERLIN_PINCTRL_FUNCTION(0x5, "vclki")),
> + BERLIN_PINCTRL_GROUP("GAV12", 0x28, 0x3, 0x0f,
> + BERLIN_PINCTRL_FUNCTION(0x0, "avio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "i2s2"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "i2s1")),
> + BERLIN_PINCTRL_GROUP("GAV13", 0x28, 0x3, 0x12,
> + BERLIN_PINCTRL_FUNCTION(0x0, "avio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "i2s2")),
> + BERLIN_PINCTRL_GROUP("GAV14", 0x28, 0x3, 0x15,
> + BERLIN_PINCTRL_FUNCTION(0x0, "avio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "i2s2"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "i2s1")),
> + BERLIN_PINCTRL_GROUP("GAV15", 0x28, 0x3, 0x18,
> + BERLIN_PINCTRL_FUNCTION(0x0, "avio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "i2s1"),
> + BERLIN_PINCTRL_FUNCTION(0x6, "dac_dbg")),
> + BERLIN_PINCTRL_GROUP("GAV16", 0x28, 0x3, 0x1b,
> + BERLIN_PINCTRL_FUNCTION(0x0, "avio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "i2s0"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "i2s1"),
> + BERLIN_PINCTRL_FUNCTION(0x4, "i2s3"),
> + BERLIN_PINCTRL_FUNCTION(0x5, "pdm"),
> + BERLIN_PINCTRL_FUNCTION(0x6, "dac_dbg")),
> + BERLIN_PINCTRL_GROUP("GAV17", 0x2c, 0x3, 0x00,
> + BERLIN_PINCTRL_FUNCTION(0x0, "avio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "i2s0"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "i2s1"),
> + BERLIN_PINCTRL_FUNCTION(0x3, "pwm"),
> + BERLIN_PINCTRL_FUNCTION(0x4, "i2s3"),
> + BERLIN_PINCTRL_FUNCTION(0x5, "pdm"),
> + BERLIN_PINCTRL_FUNCTION(0x6, "dac_dbg")),
> + BERLIN_PINCTRL_GROUP("GAV18", 0x2c, 0x3, 0x03,
> + BERLIN_PINCTRL_FUNCTION(0x0, "avio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "spdif"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "arc")),
> + BERLIN_PINCTRL_GROUP("GAV19", 0x2c, 0x3, 0x06,
> + BERLIN_PINCTRL_FUNCTION(0x0, "avio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "spdif"),
> + BERLIN_PINCTRL_FUNCTION(0x4, "i2s3"),
> + BERLIN_PINCTRL_FUNCTION(0x5, "pdm")),
> +};
> +
> +static const struct berlin_desc_group berlin2q_sysmgr_pinctrl_groups[] = {
> + /* GSM */
> + BERLIN_PINCTRL_GROUP("GSM0", 0x40, 0x2, 0x00,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "spi2"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "eth1")),
> + BERLIN_PINCTRL_GROUP("GSM1", 0x40, 0x2, 0x02,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "spi2"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "eth1")),
> + BERLIN_PINCTRL_GROUP("GSM2", 0x40, 0x2, 0x04,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "spi2"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "eddc")),
> + BERLIN_PINCTRL_GROUP("GSM3", 0x40, 0x2, 0x06,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "spi2"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "eddc")),
> + BERLIN_PINCTRL_GROUP("GSM4", 0x40, 0x1, 0x08,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "hdmi")),
> + BERLIN_PINCTRL_GROUP("GSM5", 0x40, 0x1, 0x09,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "hdmi")),
> + BERLIN_PINCTRL_GROUP("GSM6", 0x40, 0x1, 0x0a,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "hdmi")),
> + BERLIN_PINCTRL_GROUP("GSM7", 0x40, 0x1, 0x0b,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "hdmi")),
> + BERLIN_PINCTRL_GROUP("GSM8", 0x40, 0x1, 0x0c,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "hdmi")),
> + BERLIN_PINCTRL_GROUP("GSM9", 0x40, 0x1, 0x0d,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "hdmi")),
> + BERLIN_PINCTRL_GROUP("GSM10", 0x40, 0x1, 0x0e,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "led")),
> + BERLIN_PINCTRL_GROUP("GSM11", 0x40, 0x1, 0x0f,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "led")),
> + BERLIN_PINCTRL_GROUP("GSM12", 0x40, 0x2, 0x10,
> + BERLIN_PINCTRL_FUNCTION(0x0, "uart0"), /* RX/TX */
> + BERLIN_PINCTRL_FUNCTION(0x1, "irda0"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "gpio")),
> + BERLIN_PINCTRL_GROUP("GSM13", 0x40, 0x2, 0x12,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "uart0"), /* CTS/RDS */

s/RDS/RTS/

> + BERLIN_PINCTRL_FUNCTION(0x2, "uart1"), /* RX/TX */
> + BERLIN_PINCTRL_FUNCTION(0x3, "tw2")),
> + BERLIN_PINCTRL_GROUP("GSM14", 0x40, 0x2, 0x14,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "uart1"), /* RX/TX */
> + BERLIN_PINCTRL_FUNCTION(0x2, "irda1"),
> + BERLIN_PINCTRL_FUNCTION(0x3, "tw3")),

s/tw/twsi/

Sebastian

> + BERLIN_PINCTRL_GROUP("GSM15", 0x40, 0x2, 0x16,
> + BERLIN_PINCTRL_FUNCTION(0x0, "pwr"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "led"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "gpio")),
> + BERLIN_PINCTRL_GROUP("GSM16", 0x40, 0x1, 0x18,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "eddc")),
> + BERLIN_PINCTRL_GROUP("GSM17", 0x40, 0x1, 0x19,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "eddc")),
> + BERLIN_PINCTRL_GROUP("GSM18", 0x40, 0x1, 0x1a,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "eddc")),
> +};
> +
> +static const struct berlin_pinctrl_desc berlin2q_soc_pinctrl_data = {
> + .groups = berlin2q_soc_pinctrl_groups,
> + .ngroups = ARRAY_SIZE(berlin2q_soc_pinctrl_groups),
> +};
> +
> +static const struct berlin_pinctrl_desc berlin2q_sysmgr_pinctrl_data = {
> + .groups = berlin2q_sysmgr_pinctrl_groups,
> + .ngroups = ARRAY_SIZE(berlin2q_sysmgr_pinctrl_groups),
> +};
> +
> +static const struct of_device_id berlin2q_pinctrl_match[] = {
> + {
> + .compatible = "marvell,berlin2q-soc-pinctrl",
> + .data = &berlin2q_soc_pinctrl_data,
> + },
> + {
> + .compatible = "marvell,berlin2q-sysmgr-pinctrl",
> + .data = &berlin2q_sysmgr_pinctrl_data,
> + },
> + {}
> +};
> +MODULE_DEVICE_TABLE(of, berlin2q_pinctrl_match);
> +
> +static int berlin2q_pinctrl_probe(struct platform_device *pdev)
> +{
> + const struct of_device_id
> + *device = of_match_device(berlin2q_pinctrl_match, &pdev->dev);
> +
> + return berlin_pinctrl_probe(pdev, device->data);
> +}
> +
> +static struct platform_driver berlin2q_pinctrl_driver = {
> + .probe = berlin2q_pinctrl_probe,
> + .driver = {
> + .name = "berlin-bg2q-pinctrl",
> + .owner = THIS_MODULE,
> + .of_match_table = berlin2q_pinctrl_match,
> + },
> +};
> +module_platform_driver(berlin2q_pinctrl_driver);
> +
> +MODULE_AUTHOR("Antoine Ténart <[email protected]>");
> +MODULE_DESCRIPTION("Marvell Berlin BG2Q pinctrl driver");
> +MODULE_LICENSE("GPL");
>

2014-04-26 09:33:57

by Sebastian Hesselbarth

[permalink] [raw]
Subject: Re: [PATCH v2 3/7] pinctrl: berlin: add the BG2 pinctrl driver

On 04/23/2014 05:51 PM, Antoine Ténart wrote:
> Add the pin-controller driver for the Berlin BG2 SoC, with definition
> of its groups and functions. This uses the core Berlin pinctrl driver.
>
> Signed-off-by: Antoine Ténart <[email protected]>
> ---
[...]
> diff --git a/drivers/pinctrl/berlin/berlin-bg2.c b/drivers/pinctrl/berlin/berlin-bg2.c
> new file mode 100644
> index 000000000000..4a4efdc2232d
> --- /dev/null
> +++ b/drivers/pinctrl/berlin/berlin-bg2.c
> @@ -0,0 +1,251 @@
> +/*
> + * Marvell Berlin BG2 pinctrl driver.
> + *
> + * Copyright (C) 2014 Marvell Technology Group Ltd.
> + *
> + * Antoine Ténart <[email protected]>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2. This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +#include <linux/module.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +
> +#include "berlin.h"
> +
> +static const struct berlin_desc_group berlin2_soc_pinctrl_groups[] = {
> + /* G */
> + BERLIN_PINCTRL_GROUP("G0", 0x00, 0x1, 0x00,
> + BERLIN_PINCTRL_FUNCTION(0x0, "spi1"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "gpio")),
> + BERLIN_PINCTRL_GROUP("G1", 0x00, 0x2, 0x01,
> + BERLIN_PINCTRL_FUNCTION(0x0, "spi1"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "usb1")),
> + BERLIN_PINCTRL_GROUP("G2", 0x00, 0x2, 0x02,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "spi1"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "pwm"),
> + BERLIN_PINCTRL_FUNCTION(0x3, "i2s0")),
> + BERLIN_PINCTRL_GROUP("G3", 0x00, 0x2, 0x04,
> + BERLIN_PINCTRL_FUNCTION(0x0, "soc"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "spi1"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x3, "i2s1")),
> + BERLIN_PINCTRL_GROUP("G4", 0x00, 0x2, 0x06,
> + BERLIN_PINCTRL_FUNCTION(0x0, "spi1"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "pwm")),
> + BERLIN_PINCTRL_GROUP("G5", 0x00, 0x3, 0x08,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "sts1"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "et"),
> + /*
> + * Mode 0x3 mux i2s2 mclk *and* i2s3 mclk:
> + * add two functions so it can be used with other groups
> + * within the same subnode in the device tree
> + */
> + BERLIN_PINCTRL_FUNCTION(0x3, "i2s2"),
> + BERLIN_PINCTRL_FUNCTION(0x3, "i2s3")),
> + BERLIN_PINCTRL_GROUP("G6", 0x00, 0x2, 0x0b,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "sts0"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "et")),
> + BERLIN_PINCTRL_GROUP("G7", 0x00, 0x3, 0x0d,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "sts0"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "et"),
> + BERLIN_PINCTRL_FUNCTION(0x3, "vdac")),
> + BERLIN_PINCTRL_GROUP("G8", 0x00, 0x3, 0x10,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "sd0"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "et"),
> + BERLIN_PINCTRL_FUNCTION(0x3, "usb0_dbg"),
> + BERLIN_PINCTRL_FUNCTION(0x4, "sata_dbg"),
> + BERLIN_PINCTRL_FUNCTION(0x7, "usb1_dbg")),
> + BERLIN_PINCTRL_GROUP("G9", 0x00, 0x3, 0x13,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "sd0"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "et"),
> + BERLIN_PINCTRL_FUNCTION(0x3, "usb0_dbg"),
> + BERLIN_PINCTRL_FUNCTION(0x4, "sata_dbg"),
> + BERLIN_PINCTRL_FUNCTION(0x7, "usb1_dbg")),
> + BERLIN_PINCTRL_GROUP("G10", 0x00, 0x2, 0x16,
> + BERLIN_PINCTRL_FUNCTION(0x0, "soc"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "tw0"),

s/tw/twsi/ and all below.

> + BERLIN_PINCTRL_FUNCTION(0x2, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x3, "ptp")),
> + BERLIN_PINCTRL_GROUP("G11", 0x00, 0x2, 0x18,
> + BERLIN_PINCTRL_FUNCTION(0x0, "soc"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "tw1"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x3, "eddc")),
> + BERLIN_PINCTRL_GROUP("G12", 0x00, 0x3, 0x1a,
> + BERLIN_PINCTRL_FUNCTION(0x0, "sts2"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "sata"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "sd1"),
> + BERLIN_PINCTRL_FUNCTION(0x3, "usb0_dbg"),
> + BERLIN_PINCTRL_FUNCTION(0x4, "sts1"),
> + BERLIN_PINCTRL_FUNCTION(0x7, "usb1_dbg")),
> + BERLIN_PINCTRL_GROUP("G13", 0x04, 0x3, 0x00,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "sata"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "sd1"),
> + BERLIN_PINCTRL_FUNCTION(0x3, "usb0_dbg"),
> + BERLIN_PINCTRL_FUNCTION(0x4, "sts1"),
> + BERLIN_PINCTRL_FUNCTION(0x7, "usb1_dbg")),
> + BERLIN_PINCTRL_GROUP("G14", 0x04, 0x1, 0x03,
> + BERLIN_PINCTRL_FUNCTION_UNKNOW),
> + BERLIN_PINCTRL_GROUP("G15", 0x04, 0x2, 0x04,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "et"),
> + BERLIN_PINCTRL_FUNCTION(0x3, "osco")),
> + BERLIN_PINCTRL_GROUP("G16", 0x04, 0x3, 0x06,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "dvio"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "fp")),
> + BERLIN_PINCTRL_GROUP("G17", 0x04, 0x3, 0x09,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "dvio"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "fp")),
> + BERLIN_PINCTRL_GROUP("G18", 0x04, 0x1, 0x0c,
> + BERLIN_PINCTRL_FUNCTION(0x0, "pll"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "i2s0")),
> + BERLIN_PINCTRL_GROUP("G19", 0x04, 0x1, 0x0d,
> + BERLIN_PINCTRL_FUNCTION(0x0, "i2s0"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "pwm")),
> + BERLIN_PINCTRL_GROUP("G20", 0x04, 0x1, 0x0e,
> + BERLIN_PINCTRL_FUNCTION(0x0, "spdif"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "arc")),
> + BERLIN_PINCTRL_GROUP("G21", 0x04, 0x3, 0x0f,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "dvio"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "fp"),
> + BERLIN_PINCTRL_FUNCTION(0x3, "adac_dbg"),
> + BERLIN_PINCTRL_FUNCTION(0x4, "pdm_a"), /* gpio17..19,pdm */
> + BERLIN_PINCTRL_FUNCTION(0x7, "pdm_b")), /* gpio12..14,pdm */
> + BERLIN_PINCTRL_GROUP("G22", 0x04, 0x3, 0x12,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "dv0"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "fp"),
> + BERLIN_PINCTRL_FUNCTION(0x3, "tw0"),
> + BERLIN_PINCTRL_FUNCTION(0x4, "pwm")),
> + BERLIN_PINCTRL_GROUP("G23", 0x04, 0x3, 0x15,
> + BERLIN_PINCTRL_FUNCTION(0x0, "vclki"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "dv0"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "fp"),
> + BERLIN_PINCTRL_FUNCTION(0x3, "i2s0"),
> + BERLIN_PINCTRL_FUNCTION(0x4, "pwm"),
> + BERLIN_PINCTRL_FUNCTION(0x7, "pdm")),
> + BERLIN_PINCTRL_GROUP("G24", 0x04, 0x2, 0x18,
> + BERLIN_PINCTRL_FUNCTION(0x0, "i2s2"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "i2s1")),
> + BERLIN_PINCTRL_GROUP("G25", 0x04, 0x2, 0x1a,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "nand"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "i2s2")),
> + BERLIN_PINCTRL_GROUP("G26", 0x04, 0x1, 0x1c,
> + BERLIN_PINCTRL_FUNCTION(0x0, "nand"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "emmc")),
> + BERLIN_PINCTRL_GROUP("G27", 0x04, 0x1, 0x1d,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "nand")),
> + BERLIN_PINCTRL_GROUP("G28", 0x04, 0x2, 0x1e,
> + BERLIN_PINCTRL_FUNCTION(0x0, "dvo"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "sp")),
> +};
> +
> +static const struct berlin_desc_group berlin2_sysmgr_pinctrl_groups[] = {
> + /* GSM */
> + BERLIN_PINCTRL_GROUP("GSM0", 0x40, 0x2, 0x00,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "spi2"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "eth1")),
> + BERLIN_PINCTRL_GROUP("GSM1", 0x40, 0x2, 0x02,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "spi2"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "eth1")),
> + BERLIN_PINCTRL_GROUP("GSM2", 0x40, 0x2, 0x04,
> + BERLIN_PINCTRL_FUNCTION(0x0, "tw2"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "spi2")),
> + BERLIN_PINCTRL_GROUP("GSM3", 0x40, 0x2, 0x06,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "uart0"), /* CTS/RDS */

s/RDS/RTS/

Sebastian

> + BERLIN_PINCTRL_FUNCTION(0x2, "uart2"), /* RX/TX */
> + BERLIN_PINCTRL_FUNCTION(0x3, "tw2")),
> + BERLIN_PINCTRL_GROUP("GSM4", 0x40, 0x2, 0x08,
> + BERLIN_PINCTRL_FUNCTION(0x0, "uart0"), /* RX/TX */
> + BERLIN_PINCTRL_FUNCTION(0x1, "irda0")),
> + BERLIN_PINCTRL_GROUP("GSM5", 0x40, 0x2, 0x0a,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "uart1"), /* RX/TX */
> + BERLIN_PINCTRL_FUNCTION(0x2, "irda1"),
> + BERLIN_PINCTRL_FUNCTION(0x3, "tw3")),
> + BERLIN_PINCTRL_GROUP("GSM6", 0x40, 0x2, 0x0c,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "spi2"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "clki")),
> + BERLIN_PINCTRL_GROUP("GSM7", 0x40, 0x1, 0x0e,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "hdmi")),
> + BERLIN_PINCTRL_GROUP("GSM8", 0x40, 0x1, 0x0f,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "hdmi")),
> + BERLIN_PINCTRL_GROUP("GSM9", 0x40, 0x1, 0x10,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "led")),
> + BERLIN_PINCTRL_GROUP("GSM10", 0x40, 0x1, 0x11,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "led")),
> + BERLIN_PINCTRL_GROUP("GSM11", 0x40, 0x1, 0x12,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "led")),
> +};
> +
> +static const struct berlin_pinctrl_desc berlin2_soc_pinctrl_data = {
> + .groups = berlin2_soc_pinctrl_groups,
> + .ngroups = ARRAY_SIZE(berlin2_soc_pinctrl_groups),
> +};
> +
> +static const struct berlin_pinctrl_desc berlin2_sysmgr_pinctrl_data = {
> + .groups = berlin2_sysmgr_pinctrl_groups,
> + .ngroups = ARRAY_SIZE(berlin2_sysmgr_pinctrl_groups),
> +};
> +
> +static const struct of_device_id berlin2_pinctrl_match[] = {
> + {
> + .compatible = "marvell,berlin2-soc-pinctrl",
> + .data = &berlin2_soc_pinctrl_data
> + },
> + {
> + .compatible = "marvell,berlin2-sysmgr-pinctrl",
> + .data = &berlin2_sysmgr_pinctrl_data
> + },
> + {}
> +};
> +MODULE_DEVICE_TABLE(of, berlin2_pinctrl_match);
> +
> +static int berlin2_pinctrl_probe(struct platform_device *pdev)
> +{
> + const struct of_device_id
> + *device = of_match_device(berlin2_pinctrl_match, &pdev->dev);
> +
> + return berlin_pinctrl_probe(pdev, device->data);
> +}
> +
> +static struct platform_driver berlin2_pinctrl_driver = {
> + .probe = berlin2_pinctrl_probe,
> + .driver = {
> + .name = "berlin-bg2-pinctrl",
> + .owner = THIS_MODULE,
> + .of_match_table = berlin2_pinctrl_match,
> + },
> +};
> +module_platform_driver(berlin2_pinctrl_driver);
> +
> +MODULE_AUTHOR("Antoine Ténart <[email protected]>");
> +MODULE_DESCRIPTION("Marvell Berlin BG2 pinctrl driver");
> +MODULE_LICENSE("GPL");
>

2014-04-26 09:40:49

by Sebastian Hesselbarth

[permalink] [raw]
Subject: Re: [PATCH v2 4/7] pinctrl: berlin: add the BG2CD pinctrl driver

On 04/23/2014 05:51 PM, Antoine Ténart wrote:
> Add the pin-controller driver for the Berlin BG2CD SoC, with definition
> of its groups and functions. This uses the core Berlin pinctrl driver.
>
> Signed-off-by: Antoine Ténart <[email protected]>
> ---
[...]
> diff --git a/drivers/pinctrl/berlin/berlin-bg2cd.c b/drivers/pinctrl/berlin/berlin-bg2cd.c
> new file mode 100644
> index 000000000000..a12da1828bc9
> --- /dev/null
> +++ b/drivers/pinctrl/berlin/berlin-bg2cd.c
> @@ -0,0 +1,194 @@
> +/*
> + * Marvell Berlin BG2CD pinctrl driver.
> + *
> + * Copyright (C) 2014 Marvell Technology Group Ltd.
> + *
> + * Antoine Ténart <[email protected]>
> + *
> + * This file is licensed under the terms of the GNU General Public
> + * License version 2. This program is licensed "as is" without any
> + * warranty of any kind, whether express or implied.
> + */
> +
> +#include <linux/module.h>
> +#include <linux/of_device.h>
> +#include <linux/platform_device.h>
> +
> +#include "berlin.h"
> +
> +static const struct berlin_desc_group berlin2cd_soc_pinctrl_groups[] = {
> + /* G */
> + BERLIN_PINCTRL_GROUP("G0", 0x00, 0x1, 0x00,
> + BERLIN_PINCTRL_FUNCTION(0x0, "jtag"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "led"),
> + BERLIN_PINCTRL_FUNCTION(0x3, "pwm")),
> + BERLIN_PINCTRL_GROUP("G1", 0x00, 0x2, 0x01,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "sd0"),
> + BERLIN_PINCTRL_FUNCTION(0x6, "usb0_dbg"),
> + BERLIN_PINCTRL_FUNCTION(0x7, "usb1_dbg")),
> + BERLIN_PINCTRL_GROUP("G2", 0x00, 0x2, 0x02,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "sd0"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "fe"),
> + BERLIN_PINCTRL_FUNCTION(0x3, "pll"),
> + BERLIN_PINCTRL_FUNCTION(0x6, "usb0_dbg"),
> + BERLIN_PINCTRL_FUNCTION(0x7, "usb1_dbg")),
> + BERLIN_PINCTRL_GROUP("G3", 0x00, 0x2, 0x04,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "sd0"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "tw2"),

s/tw/twsi/ and for all below.

> + BERLIN_PINCTRL_FUNCTION(0x3, "pll"),
> + BERLIN_PINCTRL_FUNCTION(0x4, "fe"),
> + BERLIN_PINCTRL_FUNCTION(0x6, "usb0_dbg"),
> + BERLIN_PINCTRL_FUNCTION(0x7, "usb1_dbg")),
> + BERLIN_PINCTRL_GROUP("G4", 0x00, 0x2, 0x06,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "sd0"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "tw3"),
> + BERLIN_PINCTRL_FUNCTION(0x3, "pll"),
> + BERLIN_PINCTRL_FUNCTION(0x4, "pwm"),
> + BERLIN_PINCTRL_FUNCTION(0x6, "usb0_dbg"),
> + BERLIN_PINCTRL_FUNCTION(0x7, "usb1_dbg")),
> + BERLIN_PINCTRL_GROUP("G5", 0x00, 0x3, 0x08,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "sd0"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "tw3"),
> + BERLIN_PINCTRL_FUNCTION(0x3, "arc"),
> + BERLIN_PINCTRL_FUNCTION(0x4, "pwm"),
> + BERLIN_PINCTRL_FUNCTION(0x6, "usb0_dbg"),
> + BERLIN_PINCTRL_FUNCTION(0x7, "usb1_dbg")),
> + BERLIN_PINCTRL_GROUP("G6", 0x00, 0x2, 0x0b,
> + BERLIN_PINCTRL_FUNCTION(0x0, "uart0"), /* RX/TX */
> + BERLIN_PINCTRL_FUNCTION(0x1, "gpio")),
> + BERLIN_PINCTRL_GROUP("G7", 0x00, 0x3, 0x0d,
> + BERLIN_PINCTRL_FUNCTION(0x0, "eddc"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "tw1"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "gpio")),
> + BERLIN_PINCTRL_GROUP("G8", 0x00, 0x3, 0x10,
> + BERLIN_PINCTRL_FUNCTION(0x0, "ss0"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "gpio")),
> + BERLIN_PINCTRL_GROUP("G9", 0x00, 0x3, 0x13,
> + BERLIN_PINCTRL_FUNCTION(0x0, "gpio"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "spi1"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "tw0")),
> + BERLIN_PINCTRL_GROUP("G10", 0x00, 0x2, 0x16,
> + BERLIN_PINCTRL_FUNCTION(0x0, "spi1"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "gpio")),
> + BERLIN_PINCTRL_GROUP("G11", 0x00, 0x2, 0x18,
> + BERLIN_PINCTRL_FUNCTION(0x0, "spi1"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "gpio")),
> + BERLIN_PINCTRL_GROUP("G12", 0x00, 0x3, 0x1a,
> + BERLIN_PINCTRL_FUNCTION(0x0, "usb1"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "gpio")),
> + BERLIN_PINCTRL_GROUP("G13", 0x04, 0x3, 0x00,
> + BERLIN_PINCTRL_FUNCTION(0x0, "nand"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "usb0_dbg"),
> + BERLIN_PINCTRL_FUNCTION(0x2, "usb1_dbg")),
> + BERLIN_PINCTRL_GROUP("G14", 0x04, 0x1, 0x03,
> + BERLIN_PINCTRL_FUNCTION(0x0, "nand"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "gpio")),
> + BERLIN_PINCTRL_GROUP("G15", 0x04, 0x2, 0x04,
> + BERLIN_PINCTRL_FUNCTION(0x0, "jtag"),
> + BERLIN_PINCTRL_FUNCTION(0x1, "gpio")),
> + BERLIN_PINCTRL_GROUP("G16", 0x04, 0x3, 0x06,
> + BERLIN_PINCTRL_FUNCTION_UNKNOW),

Remember to s/UNKNOW/UNKNOWN/

Sebastian

> + BERLIN_PINCTRL_GROUP("G17", 0x04, 0x3, 0x09,
> + BERLIN_PINCTRL_FUNCTION_UNKNOW),
> + BERLIN_PINCTRL_GROUP("G18", 0x04, 0x1, 0x0c,
> + BERLIN_PINCTRL_FUNCTION_UNKNOW),
> + BERLIN_PINCTRL_GROUP("G19", 0x04, 0x1, 0x0d,
> + BERLIN_PINCTRL_FUNCTION_UNKNOW),
> + BERLIN_PINCTRL_GROUP("G20", 0x04, 0x1, 0x0e,
> + BERLIN_PINCTRL_FUNCTION_UNKNOW),
> + BERLIN_PINCTRL_GROUP("G21", 0x04, 0x3, 0x0f,
> + BERLIN_PINCTRL_FUNCTION_UNKNOW),
> + BERLIN_PINCTRL_GROUP("G22", 0x04, 0x3, 0x12,
> + BERLIN_PINCTRL_FUNCTION_UNKNOW),
> + BERLIN_PINCTRL_GROUP("G23", 0x04, 0x3, 0x15,
> + BERLIN_PINCTRL_FUNCTION_UNKNOW),
> + BERLIN_PINCTRL_GROUP("G24", 0x04, 0x2, 0x18,
> + BERLIN_PINCTRL_FUNCTION_UNKNOW),
> + BERLIN_PINCTRL_GROUP("G25", 0x04, 0x2, 0x1a,
> + BERLIN_PINCTRL_FUNCTION_UNKNOW),
> + BERLIN_PINCTRL_GROUP("G26", 0x04, 0x1, 0x1c,
> + BERLIN_PINCTRL_FUNCTION_UNKNOW),
> + BERLIN_PINCTRL_GROUP("G27", 0x04, 0x1, 0x1d,
> + BERLIN_PINCTRL_FUNCTION_UNKNOW),
> + BERLIN_PINCTRL_GROUP("G28", 0x04, 0x2, 0x1e,
> + BERLIN_PINCTRL_FUNCTION_UNKNOW),
> +};
> +
> +static const struct berlin_desc_group berlin2cd_sysmgr_pinctrl_groups[] = {
> + /* GSM */
> + BERLIN_PINCTRL_GROUP("GSM0", 0x40, 0x2, 0x00,
> + BERLIN_PINCTRL_FUNCTION_UNKNOW),
> + BERLIN_PINCTRL_GROUP("GSM1", 0x40, 0x2, 0x02,
> + BERLIN_PINCTRL_FUNCTION_UNKNOW),
> + BERLIN_PINCTRL_GROUP("GSM2", 0x40, 0x2, 0x04,
> + BERLIN_PINCTRL_FUNCTION_UNKNOW),
> + BERLIN_PINCTRL_GROUP("GSM3", 0x40, 0x2, 0x06,
> + BERLIN_PINCTRL_FUNCTION_UNKNOW),
> + BERLIN_PINCTRL_GROUP("GSM4", 0x40, 0x2, 0x08,
> + BERLIN_PINCTRL_FUNCTION_UNKNOW),
> + BERLIN_PINCTRL_GROUP("GSM5", 0x40, 0x2, 0x0a,
> + BERLIN_PINCTRL_FUNCTION_UNKNOW),
> + BERLIN_PINCTRL_GROUP("GSM6", 0x40, 0x2, 0x0c,
> + BERLIN_PINCTRL_FUNCTION_UNKNOW),
> + BERLIN_PINCTRL_GROUP("GSM7", 0x40, 0x1, 0x0e,
> + BERLIN_PINCTRL_FUNCTION_UNKNOW),
> + BERLIN_PINCTRL_GROUP("GSM8", 0x40, 0x1, 0x0f,
> + BERLIN_PINCTRL_FUNCTION_UNKNOW),
> + BERLIN_PINCTRL_GROUP("GSM9", 0x40, 0x1, 0x10,
> + BERLIN_PINCTRL_FUNCTION_UNKNOW),
> + BERLIN_PINCTRL_GROUP("GSM10", 0x40, 0x1, 0x11,
> + BERLIN_PINCTRL_FUNCTION_UNKNOW),
> + BERLIN_PINCTRL_GROUP("GSM11", 0x40, 0x1, 0x12,
> + BERLIN_PINCTRL_FUNCTION_UNKNOW),
> +};
> +
> +static const struct berlin_pinctrl_desc berlin2cd_soc_pinctrl_data = {
> + .groups = berlin2cd_soc_pinctrl_groups,
> + .ngroups = ARRAY_SIZE(berlin2cd_soc_pinctrl_groups),
> +};
> +
> +static const struct berlin_pinctrl_desc berlin2cd_sysmgr_pinctrl_data = {
> + .groups = berlin2cd_sysmgr_pinctrl_groups,
> + .ngroups = ARRAY_SIZE(berlin2cd_sysmgr_pinctrl_groups),
> +};
> +
> +static const struct of_device_id berlin2cd_pinctrl_match[] = {
> + {
> + .compatible = "marvell,berlin2cd-soc-pinctrl",
> + .data = &berlin2cd_soc_pinctrl_data
> + },
> + {
> + .compatible = "marvell,berlin2cd-sysmgr-pinctrl",
> + .data = &berlin2cd_sysmgr_pinctrl_data
> + },
> + {}
> +};
> +MODULE_DEVICE_TABLE(of, berlin2cd_pinctrl_match);
> +
> +static int berlin2cd_pinctrl_probe(struct platform_device *pdev)
> +{
> + const struct of_device_id
> + *device = of_match_device(berlin2cd_pinctrl_match, &pdev->dev);
> +
> + return berlin_pinctrl_probe(pdev, device->data);
> +}
> +
> +static struct platform_driver berlin2cd_pinctrl_driver = {
> + .probe = berlin2cd_pinctrl_probe,
> + .driver = {
> + .name = "berlin-bg2cd-pinctrl",
> + .owner = THIS_MODULE,
> + .of_match_table = berlin2cd_pinctrl_match,
> + },
> +};
> +module_platform_driver(berlin2cd_pinctrl_driver);
> +
> +MODULE_AUTHOR("Antoine Ténart <[email protected]>");
> +MODULE_DESCRIPTION("Marvell Berlin BG2CD pinctrl driver");
> +MODULE_LICENSE("GPL");
>

2014-04-26 09:44:36

by Sebastian Hesselbarth

[permalink] [raw]
Subject: Re: [PATCH v2 6/7] Documentation: add the Marvell Berlin pinctrl documentation

On 04/23/2014 05:51 PM, Antoine Ténart wrote:
> Add the documentation related to the Berlin pin-controller driver and
> explain how to configure this group based controller.
>
> Signed-off-by: Antoine Ténart <[email protected]>
> ---
> .../bindings/pinctrl/marvell,berlin-pinctrl.txt | 44 ++++++++++++++++++++++
> 1 file changed, 44 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/pinctrl/marvell,berlin-pinctrl.txt
>
> diff --git a/Documentation/devicetree/bindings/pinctrl/marvell,berlin-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/marvell,berlin-pinctrl.txt
> new file mode 100644
> index 000000000000..c59671ac6b54
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/pinctrl/marvell,berlin-pinctrl.txt
> @@ -0,0 +1,44 @@
> +* Pin-controller driver for the Marvell Berlin SoCs
> +
> +The pins controlled by the Marvell Berlin controller are organized in groups.
> +Configuration is done by group, so no actual pin information is needed.
> +
> +Be aware the Marvell Berlin datasheets use the keyword 'mode' for what is called
> +a 'function' in the pin-controller subsystem.
> +
> +Required properties:
> +- compatible: should be one of: "marvell,berlin2-soc-pinctrl",

nit: add the line break right after "one of:".

> + "marvell,berlin2-sysmgr-pinctrl",
> + "marvell,berlin2cd-soc-pinctrl",
> + "marvell,berlin2cd-sysmgr-pinctrl",
> + "marvell,berlin2q-soc-pinctrl"
> + "marvell,berlin2q-sysmgr-pinctrl"
> +- reg: registers physical address and length of the pin controller.
> +
> +Please refer to pinctrl-bindings.txt in this directory for details of the
> +common pin-controller bindings used by client devices.
> +
> +A pin-controller node should contain subnodes representing the pin group
> +configurations, one per group. Each subnode has the group name and the muxing

",one per group" isn't correct, is it? You can have one subnode with
more than one group, like in your example below.

Sebastian

> +function used.
> +
> +Required subnode-properties:
> +- marvell,groups: a list of strings describing the group names.
> +- marvell,function: a string describing the function used to mux the groups.
> +
> +Example:
> +
> +sm_pinctrl: pin-controller@0 {
> + compatible = "marvell,berlin2q-sysmgr-pinctrl";
> + reg = <0xfc0000 0x44>;
> +
> + uart0_pmux: uart0-pmux {
> + marvell,groups = "GSM12", "GSM13";
> + marvell,function = "uart0";
> + };
> +}
> +
> +&uart0 {
> + pinctrl-0 = <&uart0_pmux>;
> + pinctrl-names = "default";
> +};
>

2014-04-26 09:51:54

by Sebastian Hesselbarth

[permalink] [raw]
Subject: Re: [PATCH v2 7/7] ARM: dts: berlin: add the pinctrl node and muxing setup for uarts

On 04/23/2014 05:51 PM, Antoine Ténart wrote:
> The uart0 pinmux configuration is in the dtsi because uart0 will always
> use uart0-pmux to work, no other possibility. Same thing for uart1.
>
> Signed-off-by: Antoine Ténart <[email protected]>
> ---
> arch/arm/boot/dts/berlin2.dtsi | 24 ++++++++++++++++++++++++
> arch/arm/boot/dts/berlin2cd.dtsi | 17 +++++++++++++++++
> arch/arm/boot/dts/berlin2q.dtsi | 24 ++++++++++++++++++++++++
> 3 files changed, 65 insertions(+)
>
> diff --git a/arch/arm/boot/dts/berlin2.dtsi b/arch/arm/boot/dts/berlin2.dtsi
> index 56a1af2f1052..9a13891c38a3 100644
> --- a/arch/arm/boot/dts/berlin2.dtsi
> +++ b/arch/arm/boot/dts/berlin2.dtsi
> @@ -176,6 +176,11 @@
> };
> };
>
> + soc_pinctrl: pin-controller@ea0000 {
> + compatible = "marvell,berlin2-soc-pinctrl";
> + reg = <0xea0000 0x4c>;
> + };
> +
> apb@fc0000 {
> compatible = "simple-bus";
> #address-cells = <1>;
> @@ -184,6 +189,21 @@
> ranges = <0 0xfc0000 0x10000>;
> interrupt-parent = <&sic>;
>
> + sm_pinctrl: pin-controller@0000 {
> + compatible = "marvell,berlin2-sysmgr-pinctrl";
> + reg = <0x0000 0x44>;
> +
> + uart0_pmux: uart0-pmux {
> + marvell,groups = "GSM4";
> + marvell,function = "uart0";
> + };
> +
> + uart1_pmux: uart1-pmux {
> + marvell,groups = "GSM5";
> + marvell,function = "uart1";
> + };

There is three uarts in BG2, we have the node already. Please add

uart2_pmux: uart2-pmux {
marvell,groups = "GSM3";
marvell,function = "uart2";
};

here and in the corresponding node:

pinctrl-0 = <&uart2_pmux>;
pinctrl-names = "default";

Sebastian

> + };
> +
> uart0: serial@9000 {
> compatible = "snps,dw-apb-uart";
> reg = <0x9000 0x100>;
> @@ -191,6 +211,8 @@
> reg-io-width = <1>;
> interrupts = <8>;
> clocks = <&smclk>;
> + pinctrl-0 = <&uart0_pmux>;
> + pinctrl-names = "default";
> status = "disabled";
> };
>
> @@ -201,6 +223,8 @@
> reg-io-width = <1>;
> interrupts = <9>;
> clocks = <&smclk>;
> + pinctrl-0 = <&uart1_pmux>;
> + pinctrl-names = "default";
> status = "disabled";
> };
>
> diff --git a/arch/arm/boot/dts/berlin2cd.dtsi b/arch/arm/boot/dts/berlin2cd.dtsi
> index 094968c27533..a802d3fe5da6 100644
> --- a/arch/arm/boot/dts/berlin2cd.dtsi
> +++ b/arch/arm/boot/dts/berlin2cd.dtsi
> @@ -169,6 +169,11 @@
> };
> };
>
> + soc_pinctrl: pin-controller@ae0000 {
> + compatible = "marvell,berlin2cd-soc-pinctrl";
> + reg = <0xea0000 0x4c>;
> + };
> +
> apb@fc0000 {
> compatible = "simple-bus";
> #address-cells = <1>;
> @@ -177,6 +182,16 @@
> ranges = <0 0xfc0000 0x10000>;
> interrupt-parent = <&sic>;
>
> + sm_pinctrl: pin-controller@0000 {
> + compatible = "marvell,berlin2cd-sysmgr-pinctrl";
> + reg = <0x0000 0x44>;
> +
> + uart0_pmux: uart0-pmux {
> + marvell,groups = "G6";
> + marvell,function = "uart0";
> + };
> + };
> +
> uart0: serial@9000 {
> compatible = "snps,dw-apb-uart";
> reg = <0x9000 0x100>;
> @@ -184,6 +199,8 @@
> reg-io-width = <1>;
> interrupts = <8>;
> clocks = <&smclk>;
> + pinctrl-0 = <&uart0_pmux>;
> + pinctrl-names = "default";
> status = "disabled";
> };
>
> diff --git a/arch/arm/boot/dts/berlin2q.dtsi b/arch/arm/boot/dts/berlin2q.dtsi
> index 07452a7483fa..734debbf072f 100644
> --- a/arch/arm/boot/dts/berlin2q.dtsi
> +++ b/arch/arm/boot/dts/berlin2q.dtsi
> @@ -183,6 +183,11 @@
> };
> };
>
> + soc_pinctrl: pin-controller@ea0000 {
> + compatible = "marvell,berlin2q-soc-pinctrl";
> + reg = <0xea0000 0x4c>;
> + };
> +
> apb@fc0000 {
> compatible = "simple-bus";
> #address-cells = <1>;
> @@ -198,6 +203,8 @@
> interrupts = <8>;
> clocks = <&smclk>;
> reg-shift = <2>;
> + pinctrl-0 = <&uart0_pmux>;
> + pinctrl-names = "default";
> status = "disabled";
> };
>
> @@ -208,9 +215,26 @@
> interrupts = <9>;
> clocks = <&smclk>;
> reg-shift = <2>;
> + pinctrl-0 = <&uart1_pmux>;
> + pinctrl-names = "default";
> status = "disabled";
> };
>
> + sm_pinctrl: pin-controller@d000 {
> + compatible = "marvell,berlin2q-sysmgr-pinctrl";
> + reg = <0xd000 0x44>;
> +
> + uart0_pmux: uart0-pmux {
> + marvell,groups = "GSM12";
> + marvell,function = "uart0";
> + };
> +
> + uart1_pmux: uart1-pmux {
> + marvell,groups = "GSM14";
> + marvell,function = "uart1";
> + };
> + };
> +
> sic: interrupt-controller@e000 {
> compatible = "snps,dw-apb-ictl";
> reg = <0xe000 0x30>;
>

2014-04-26 09:53:52

by Sebastian Hesselbarth

[permalink] [raw]
Subject: Re: [PATCH v2 0/7] ARM: berlin: add pinctrl support

On 04/25/2014 11:13 AM, Linus Walleij wrote:
> On Wed, Apr 23, 2014 at 5:51 PM, Antoine Ténart
> <[email protected]> wrote:
>
>> This series adds support for the Marvell Berlin pin-controller, allowing
>> to configure the pin muxing from the device tree.
>
> I've looked over the patch series and there is nothing really controversial in
> there, but I'm waiting for Thomas & Sebastian to provide Reviewed-by
> tags.

Ok, great! I had some minor remarks but mainly cosmetic nits. As soon
as Antoine resends a final v3, feel free to take patches 1-4. I will
pick up 6 and 7 then.

Sebastian