* [PATCH v2 1/2] tegra20: add pinctrl driver
@ 2013-05-10 18:28 Lucas Stach
2013-05-10 18:28 ` [PATCH v2 2/2] tegra: paz00: import pinconfig from Linux Lucas Stach
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Lucas Stach @ 2013-05-10 18:28 UTC (permalink / raw)
To: barebox
This adds a pinctrl driver for the Tegra 20 line of SoCs. It only
supports the three basic pinconfiguration settings function mux,
tristate control and pullup/down control.
The driver understands the same devicetree bindings as the Linux one,
unimplemented pinconfiguration options will be ignored.
Signed-off-by: Lucas Stach <dev@lynxeye.de>
---
v2:
- use named regs
- check for return value of request_mem_region
---
arch/arm/dts/tegra20.dtsi | 8 +
arch/arm/mach-tegra/Kconfig | 1 +
drivers/pinctrl/Kconfig | 6 +
drivers/pinctrl/Makefile | 1 +
drivers/pinctrl/pinctrl-tegra20.c | 346 ++++++++++++++++++++++++++++++++++++++
5 files changed, 362 insertions(+)
create mode 100644 drivers/pinctrl/pinctrl-tegra20.c
diff --git a/arch/arm/dts/tegra20.dtsi b/arch/arm/dts/tegra20.dtsi
index b7d1e27..f63ead8 100644
--- a/arch/arm/dts/tegra20.dtsi
+++ b/arch/arm/dts/tegra20.dtsi
@@ -34,6 +34,14 @@
interrupt-controller;
};
+ pinmux: pinmux {
+ compatible = "nvidia,tegra20-pinmux";
+ reg = <0x70000014 0x10 /* Tri-state registers */
+ 0x70000080 0x20 /* Mux registers */
+ 0x700000a0 0x14 /* Pull-up/down registers */
+ 0x70000868 0xa8>; /* Pad control registers */
+ };
+
pmc {
compatible = "nvidia,tegra20-pmc";
reg = <0x7000e400 0x400>;
diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig
index 965e7ab..53ae070 100644
--- a/arch/arm/mach-tegra/Kconfig
+++ b/arch/arm/mach-tegra/Kconfig
@@ -5,6 +5,7 @@ choice
config ARCH_TEGRA_2x_SOC
bool "Tegra 20"
+ select PINCTRL_TEGRA20
endchoice
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index e6aee50..0b859b8 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -25,4 +25,10 @@ config PINCTRL_IMX_IOMUX_V3
help
This iomux controller is found on i.MX25,35,51,53,6.
+config PINCTRL_TEGRA20
+ select PINCTRL
+ bool "Tegra 20 pinmux"
+ help
+ The pinmux controller found on the Tegra 20 line of SoCs.
+
endmenu
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index e9272d0..169ed18 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -2,3 +2,4 @@ obj-$(CONFIG_PINCTRL) += pinctrl.o
obj-$(CONFIG_PINCTRL_IMX_IOMUX_V1) += imx-iomux-v1.o
obj-$(CONFIG_PINCTRL_IMX_IOMUX_V2) += imx-iomux-v2.o
obj-$(CONFIG_PINCTRL_IMX_IOMUX_V3) += imx-iomux-v3.o
+obj-$(CONFIG_PINCTRL_TEGRA20) += pinctrl-tegra20.o
diff --git a/drivers/pinctrl/pinctrl-tegra20.c b/drivers/pinctrl/pinctrl-tegra20.c
new file mode 100644
index 0000000..053981f
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-tegra20.c
@@ -0,0 +1,346 @@
+/*
+ * Copyright (C) 2013 Lucas Stach <l.stach@pengutronix.de>
+ *
+ * Partly based on code
+ * Copyright (C) 2011-2012 NVIDIA Corporation <www.nvidia.com>
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * @file
+ * @brief Device driver for the Tegra 20 pincontrol hardware module.
+ */
+
+#include <common.h>
+#include <init.h>
+#include <io.h>
+#include <malloc.h>
+#include <pinctrl.h>
+
+struct pinctrl_tegra20 {
+ struct {
+ u32 __iomem *tri;
+ u32 __iomem *mux;
+ u32 __iomem *pull;
+ } regs;
+ struct pinctrl_device pinctrl;
+};
+
+struct tegra20_pingroup {
+ const char *name;
+ const char *funcs[4];
+ s16 trictrl_id;
+ s16 muxctrl_id;
+ s16 pullctrl_id;
+};
+
+#define PG(pg_name, f0, f1, f2, f3, tri, mux, pull) \
+ { \
+ .name = #pg_name, \
+ .funcs = { #f0, #f1, #f2, #f3, }, \
+ .trictrl_id = tri, \
+ .muxctrl_id = mux, \
+ .pullctrl_id = pull \
+ }
+
+static const struct tegra20_pingroup tegra20_groups[] = {
+ /* name, f0, f1, f2, f3, tri, mux, pull */
+ PG(ata, ide, nand, gmi, rsvd4, 0, 12, 0 ),
+ PG(atb, ide, nand, gmi, sdio4, 1, 8, 1 ),
+ PG(atc, ide, nand, gmi, sdio4, 2, 11, 2 ),
+ PG(atd, ide, nand, gmi, sdio4, 3, 10, 3 ),
+ PG(ate, ide, nand, gmi, rsvd4, 57, 6, 4 ),
+ PG(cdev1, osc, plla_out, pllm_out1, audio_sync, 4, 33, 32 ),
+ PG(cdev2, osc, ahb_clk, apb_clk, pllp_out4, 5, 34, 33 ),
+ PG(crtp, crt, rsvd2, rsvd3, rsvd4, 110, 105, 28 ),
+ PG(csus, pllc_out1, pllp_out2, pllp_out3, vi_sensor_clk, 6, 35, 60 ),
+ PG(dap1, dap1, rsvd2, gmi, sdio2, 7, 42, 5 ),
+ PG(dap2, dap2, twc, rsvd3, gmi, 8, 43, 6 ),
+ PG(dap3, dap3, rsvd2, rsvd3, rsvd4, 9, 44, 7 ),
+ PG(dap4, dap4, rsvd2, gmi, rsvd4, 10, 45, 8 ),
+ PG(ddc, i2c2, rsvd2, rsvd3, rsvd4, 63, 32, 78 ),
+ PG(dta, rsvd1, sdio2, vi, rsvd4, 11, 26, 9 ),
+ PG(dtb, rsvd1, rsvd2, vi, spi1, 12, 27, 10 ),
+ PG(dtc, rsvd1, rsvd2, vi, rsvd4, 13, 29, 11 ),
+ PG(dtd, rsvd1, sdio2, vi, rsvd4, 14, 30, 12 ),
+ PG(dte, rsvd1, rsvd2, vi, spi1, 15, 31, 13 ),
+ PG(dtf, i2c3, rsvd2, vi, rsvd4, 108, 110, 14 ),
+ PG(gma, uarte, spi3, gmi, sdio4, 28, 16, 74 ),
+ PG(gmb, ide, nand, gmi, gmi_int, 61, 46, 75 ),
+ PG(gmc, uartd, spi4, gmi, sflash, 29, 17, 76 ),
+ PG(gmd, rsvd1, nand, gmi, sflash, 62, 47, 77 ),
+ PG(gme, rsvd1, dap5, gmi, sdio4, 32, 48, 44 ),
+ PG(gpu, pwm, uarta, gmi, rsvd4, 16, 50, 26 ),
+ PG(gpu7, rtck, rsvd2, rsvd3, rsvd4, 107, 109, 19 ),
+ PG(gpv, pcie, rsvd2, rsvd3, rsvd4, 17, 49, 15 ),
+ PG(hdint, hdmi, rsvd2, rsvd3, rsvd4, 87, 18, -1 ),
+ PG(i2cp, i2cp, rsvd2, rsvd3, rsvd4, 18, 36, 17 ),
+ PG(irrx, uarta, uartb, gmi, spi4, 20, 41, 43 ),
+ PG(irtx, uarta, uartb, gmi, spi4, 19, 40, 42 ),
+ PG(kbca, kbc, nand, sdio2, emc_test0_dll, 22, 37, 20 ),
+ PG(kbcb, kbc, nand, sdio2, mio, 21, 38, 21 ),
+ PG(kbcc, kbc, nand, trace, emc_test1_dll, 58, 39, 22 ),
+ PG(kbcd, kbc, nand, sdio2, mio, 106, 108, 23 ),
+ PG(kbce, kbc, nand, owr, rsvd4, 26, 14, 65 ),
+ PG(kbcf, kbc, nand, trace, mio, 27, 13, 64 ),
+ PG(lcsn, displaya, displayb, spi3, rsvd4, 95, 70, -1 ),
+ PG(ld0, displaya, displayb, xio, rsvd4, 64, 80, -1 ),
+ PG(ld1, displaya, displayb, xio, rsvd4, 65, 81, -1 ),
+ PG(ld2, displaya, displayb, xio, rsvd4, 66, 82, -1 ),
+ PG(ld3, displaya, displayb, xio, rsvd4, 67, 83, -1 ),
+ PG(ld4, displaya, displayb, xio, rsvd4, 68, 84, -1 ),
+ PG(ld5, displaya, displayb, xio, rsvd4, 69, 85, -1 ),
+ PG(ld6, displaya, displayb, xio, rsvd4, 70, 86, -1 ),
+ PG(ld7, displaya, displayb, xio, rsvd4, 71, 87, -1 ),
+ PG(ld8, displaya, displayb, xio, rsvd4, 72, 88, -1 ),
+ PG(ld9, displaya, displayb, xio, rsvd4, 73, 89, -1 ),
+ PG(ld10, displaya, displayb, xio, rsvd4, 74, 90, -1 ),
+ PG(ld11, displaya, displayb, xio, rsvd4, 75, 91, -1 ),
+ PG(ld12, displaya, displayb, xio, rsvd4, 76, 92, -1 ),
+ PG(ld13, displaya, displayb, xio, rsvd4, 77, 93, -1 ),
+ PG(ld14, displaya, displayb, xio, rsvd4, 78, 94, -1 ),
+ PG(ld15, displaya, displayb, xio, rsvd4, 79, 95, -1 ),
+ PG(ld16, displaya, displayb, xio, rsvd4, 80, 96, -1 ),
+ PG(ld17, displaya, displayb, rsvd3, rsvd4, 81, 97, -1 ),
+ PG(ldc, displaya, displayb, rsvd3, rsvd4, 94, 71, -1 ),
+ PG(ldi, displaya, displayb, rsvd3, rsvd4, 102, 104, -1 ),
+ PG(lhp0, displaya, displayb, rsvd3, rsvd4, 82, 101, -1 ),
+ PG(lhp1, displaya, displayb, rsvd3, rsvd4, 83, 98, -1 ),
+ PG(lhp2, displaya, displayb, rsvd3, rsvd4, 84, 99, -1 ),
+ PG(lhs, displaya, displayb, xio, rsvd4, 103, 75, -1 ),
+ PG(lm0, displaya, displayb, spi3, rsvd4, 88, 77, -1 ),
+ PG(lm1, displaya, displayb, rsvd3, CRT, 89, 78, -1 ),
+ PG(lpp, displaya, displayb, rsvd3, rsvd4, 104, 103, -1 ),
+ PG(lpw0, displaya, displayb, spi3, hdmi, 99, 64, -1 ),
+ PG(lpw1, displaya, displayb, rsvd3, rsvd4, 100, 65, -1 ),
+ PG(lpw2, displaya, displayb, spi3, hdmi, 101, 66, -1 ),
+ PG(lsc0, displaya, displayb, xio, rsvd4, 91, 73, -1 ),
+ PG(lsc1, displaya, displayb, spi3, hdmi, 92, 74, -1 ),
+ PG(lsck, displaya, displayb, spi3, hdmi, 93, 72, -1 ),
+ PG(lsda, displaya, displayb, spi3, hdmi, 97, 68, -1 ),
+ PG(lsdi, displaya, displayb, spi3, rsvd4, 98, 67, -1 ),
+ PG(lspi, displaya, displayb, xio, hdmi, 96, 69, -1 ),
+ PG(lvp0, displaya, displayb, rsvd3, rsvd4, 85, 79, -1 ),
+ PG(lvp1, displaya, displayb, rsvd3, rsvd4, 86, 100, -1 ),
+ PG(lvs, displaya, displayb, xio, rsvd4, 90, 76, -1 ),
+ PG(owc, owr, rsvd2, rsvd3, rsvd4, 31, 20, 79 ),
+ PG(pmc, pwr_on, pwr_intr, rsvd3, rsvd4, 23, 105, -1 ),
+ PG(pta, i2c2, hdmi, gmi, rsvd4, 24, 107, 18 ),
+ PG(rm, i2c1, rsvd2, rsvd3, rsvd4, 25, 7, 16 ),
+ PG(sdb, uarta, pwm, sdio3, spi2, 111, 53, -1 ),
+ PG(sdc, pwm, twc, sdio3, spi3, 33, 54, 62 ),
+ PG(sdd, uarta, pwm, sdio3, spi3, 34, 55, 63 ),
+ PG(sdio1, sdio1, rsvd2, uarte, uarta, 30, 15, 73 ),
+ PG(slxa, pcie, spi4, sdio3, spi2, 36, 19, 27 ),
+ PG(slxc, spdif, spi4, sdio3, spi2, 37, 21, 29 ),
+ PG(slxd, spdif, spi4, sdio3, spi2, 38, 22, 30 ),
+ PG(slxk, pcie, spi4, sdio3, spi2, 39, 23, 31 ),
+ PG(spdi, spdif, rsvd2, i2c1, sdio2, 40, 52, 24 ),
+ PG(spdo, spdif, rsvd2, i2c1, sdio2, 41, 51, 25 ),
+ PG(spia, spi1, spi2, spi3, gmi, 42, 63, 34 ),
+ PG(spib, spi1, spi2, spi3, gmi, 43, 62, 35 ),
+ PG(spic, spi1, spi2, spi3, gmi, 44, 61, 36 ),
+ PG(spid, spi2, spi1, spi2_alt, gmi, 45, 60, 37 ),
+ PG(spie, spi2, spi1, spi2_alt, gmi, 46, 59, 38 ),
+ PG(spif, spi3, spi1, spi2, rsvd4, 47, 58, 39 ),
+ PG(spig, spi3, spi2, spi2_alt, i2c1, 48, 57, 40 ),
+ PG(spih, spi3, spi2, spi2_alt, i2c1, 49, 56, 41 ),
+ PG(uaa, spi3, mipi_hs, uarta, ulpi, 50, 0, 48 ),
+ PG(uab, spi2, mipi_hs, uarta, ulpi, 51, 1, 49 ),
+ PG(uac, owr, rsvd2, rsvd3, rsvd4, 52, 2, 50 ),
+ PG(uad, irda, spdif, uarta, spi4, 53, 3, 51 ),
+ PG(uca, uartc, rsvd2, gmi, rsvd4, 54, 24, 52 ),
+ PG(ucb, uartc, pwm, gmi, rsvd4, 55, 25, 53 ),
+ PG(uda, spi1, rsvd2, uartd, ulpi, 109, 4, 72 ),
+};
+
+static void pinctrl_tegra20_set_func(struct pinctrl_tegra20 *ctrl,
+ int muxctrl_id, int func)
+{
+ u32 __iomem *regaddr = ctrl->regs.mux;
+ u32 reg;
+ int maskbit;
+
+ regaddr += muxctrl_id >> 4;
+ maskbit = (muxctrl_id << 1) & 0x1f;
+
+ reg = readl(regaddr);
+ reg &= ~(0x3 << maskbit);
+ reg |= func << maskbit;
+ writel(reg, regaddr);
+}
+
+static void pinctrl_tegra20_set_pull(struct pinctrl_tegra20 *ctrl,
+ int pullctrl_id, int pull)
+{
+ u32 __iomem *regaddr = ctrl->regs.pull;
+ u32 reg;
+ int maskbit;
+
+ regaddr += pullctrl_id >> 4;
+ maskbit = (pullctrl_id << 1) & 0x1f;
+
+ reg = readl(regaddr);
+ reg &= ~(0x3 << maskbit);
+ reg |= pull << maskbit;
+ writel(reg, regaddr);
+}
+
+static void pinctrl_tegra20_set_tristate(struct pinctrl_tegra20 *ctrl,
+ int trictrl_id, int tristate)
+{
+ u32 __iomem *regaddr = ctrl->regs.tri;
+ u32 reg;
+ int maskbit;
+
+ regaddr += trictrl_id >> 5;
+ maskbit = trictrl_id & 0x1f;
+
+ reg = readl(regaddr);
+ reg &= ~(1 << maskbit);
+ reg |= tristate << maskbit;
+ writel(reg, regaddr);
+}
+
+static int pinctrl_tegra20_set_state(struct pinctrl_device *pdev,
+ struct device_node *np)
+{
+ struct pinctrl_tegra20 *ctrl =
+ container_of(pdev, struct pinctrl_tegra20, pinctrl);
+ struct device_node *childnode;
+ int pull = -1, tri = -1, i, j, k;
+ const char *pins, *func = NULL;
+ const struct tegra20_pingroup *group;
+
+ /*
+ * At first look if the node we are pointed at has children,
+ * which we may want to visit.
+ */
+ list_for_each_entry(childnode, &np->children, parent_list)
+ pinctrl_tegra20_set_state(pdev, childnode);
+
+ /* read relevant state from devicetree */
+ of_property_read_string(np, "nvidia,function", &func);
+ of_property_read_u32_array(np, "nvidia,pull", &pull, 1);
+ of_property_read_u32_array(np, "nvidia,tristate", &tri, 1);
+
+ /* iterate over all pingroups referenced in the dt node */
+ for (i = 0; ; i++) {
+ if (of_property_read_string_index(np, "nvidia,pins", i, &pins))
+ break;
+
+ for (j = 0; j < ARRAY_SIZE(tegra20_groups); j++) {
+ if (!strcmp(pins, tegra20_groups[j].name)) {
+ group = &tegra20_groups[j];
+ break;
+ }
+ }
+ /* if no matching pingroup is found bail out */
+ if (j == ARRAY_SIZE(tegra20_groups)) {
+ dev_warn(ctrl->pinctrl.dev,
+ "invalid pingroup %s referenced in node %s\n",
+ pins, np->name);
+ continue;
+ }
+
+ if (func) {
+ for (k = 0; k < 4; k++) {
+ if (!strcmp(func, group->funcs[k]))
+ break;
+ }
+ if (k < 4)
+ pinctrl_tegra20_set_func(ctrl,
+ group->muxctrl_id, k);
+ else
+ dev_warn(ctrl->pinctrl.dev,
+ "invalid function %s for pingroup %s in node %s\n",
+ func, group->name, np->name);
+ }
+
+ if (pull >= 0) {
+ if (group->pullctrl_id >= 0)
+ pinctrl_tegra20_set_pull(ctrl,
+ group->pullctrl_id,
+ pull);
+ else
+ dev_warn(ctrl->pinctrl.dev,
+ "pingroup %s in node %s doesn't support pull configuration\n",
+ group->name, np->name);
+ }
+
+ if (tri >= 0)
+ pinctrl_tegra20_set_tristate(ctrl,
+ group->trictrl_id, tri);
+ }
+
+ return 0;
+}
+
+static struct pinctrl_ops pinctrl_tegra20_ops = {
+ .set_state = pinctrl_tegra20_set_state,
+};
+
+static int pinctrl_tegra20_probe(struct device_d *dev)
+{
+ struct pinctrl_tegra20 *ctrl;
+ int i, ret;
+ u32 **regs;
+
+ ctrl = xzalloc(sizeof(*ctrl));
+
+ /*
+ * Tegra pincontrol is split out into four independent memory ranges:
+ * tristate control, function mux, pullup/down control, pad control
+ * (from lowest to highest hardware address).
+ * We are only interested in the first three for now.
+ */
+ regs = (u32 **)&ctrl->regs;
+ for (i = 0; i <= 2; i++) {
+ regs[i] = dev_request_mem_region(dev, i);
+ if (!regs[i]) {
+ dev_err(dev, "Could not get iomem region %d\n", i);
+ return -ENODEV;
+ }
+ }
+
+ ctrl->pinctrl.dev = dev;
+ ctrl->pinctrl.ops = &pinctrl_tegra20_ops;
+
+ ret = pinctrl_register(&ctrl->pinctrl);
+ if (ret)
+ free(ctrl);
+
+ return ret;
+}
+
+static __maybe_unused struct of_device_id pinctrl_tegra20_dt_ids[] = {
+ {
+ .compatible = "nvidia,tegra20-pinmux",
+ }, {
+ /* sentinel */
+ }
+};
+
+static struct driver_d pinctrl_tegra20_driver = {
+ .name = "pinctrl-tegra20",
+ .probe = pinctrl_tegra20_probe,
+ .of_compatible = DRV_OF_COMPAT(pinctrl_tegra20_dt_ids),
+};
+
+static int pinctrl_tegra20_init(void)
+{
+ return platform_driver_register(&pinctrl_tegra20_driver);
+}
+postcore_initcall(pinctrl_tegra20_init);
--
1.8.1.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v2 2/2] tegra: paz00: import pinconfig from Linux
2013-05-10 18:28 [PATCH v2 1/2] tegra20: add pinctrl driver Lucas Stach
@ 2013-05-10 18:28 ` Lucas Stach
2013-05-10 19:03 ` [PATCH v2 1/2] tegra20: add pinctrl driver Alexander Aring
2013-10-22 15:07 ` Uwe Kleine-König
2 siblings, 0 replies; 6+ messages in thread
From: Lucas Stach @ 2013-05-10 18:28 UTC (permalink / raw)
To: barebox
Signed-off-by: Lucas Stach <dev@lynxeye.de>
---
arch/arm/dts/tegra20-paz00.dts | 216 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 216 insertions(+)
diff --git a/arch/arm/dts/tegra20-paz00.dts b/arch/arm/dts/tegra20-paz00.dts
index 09ccb8b..e8486aa 100644
--- a/arch/arm/dts/tegra20-paz00.dts
+++ b/arch/arm/dts/tegra20-paz00.dts
@@ -9,4 +9,220 @@
memory {
reg = <0x00000000 0x20000000>;
};
+
+ pinmux {
+ pinctrl-names = "default";
+ pinctrl-0 = <&state_default>;
+
+ state_default: pinmux {
+ ata {
+ nvidia,pins = "ata", "atc", "atd", "ate",
+ "dap2", "gmb", "gmc", "gmd", "spia",
+ "spib", "spic", "spid", "spie";
+ nvidia,function = "gmi";
+ };
+ atb {
+ nvidia,pins = "atb", "gma", "gme";
+ nvidia,function = "sdio4";
+ };
+ cdev1 {
+ nvidia,pins = "cdev1";
+ nvidia,function = "plla_out";
+ };
+ cdev2 {
+ nvidia,pins = "cdev2";
+ nvidia,function = "pllp_out4";
+ };
+ crtp {
+ nvidia,pins = "crtp";
+ nvidia,function = "crt";
+ };
+ csus {
+ nvidia,pins = "csus";
+ nvidia,function = "pllc_out1";
+ };
+ dap1 {
+ nvidia,pins = "dap1";
+ nvidia,function = "dap1";
+ };
+ dap3 {
+ nvidia,pins = "dap3";
+ nvidia,function = "dap3";
+ };
+ dap4 {
+ nvidia,pins = "dap4";
+ nvidia,function = "dap4";
+ };
+ ddc {
+ nvidia,pins = "ddc";
+ nvidia,function = "i2c2";
+ };
+ dta {
+ nvidia,pins = "dta", "dtb", "dtc", "dtd", "dte";
+ nvidia,function = "rsvd1";
+ };
+ dtf {
+ nvidia,pins = "dtf";
+ nvidia,function = "i2c3";
+ };
+ gpu {
+ nvidia,pins = "gpu", "sdb", "sdd";
+ nvidia,function = "pwm";
+ };
+ gpu7 {
+ nvidia,pins = "gpu7";
+ nvidia,function = "rtck";
+ };
+ gpv {
+ nvidia,pins = "gpv", "slxa", "slxk";
+ nvidia,function = "pcie";
+ };
+ hdint {
+ nvidia,pins = "hdint", "pta";
+ nvidia,function = "hdmi";
+ };
+ i2cp {
+ nvidia,pins = "i2cp";
+ nvidia,function = "i2cp";
+ };
+ irrx {
+ nvidia,pins = "irrx", "irtx";
+ nvidia,function = "uarta";
+ };
+ kbca {
+ nvidia,pins = "kbca", "kbcc", "kbce", "kbcf";
+ nvidia,function = "kbc";
+ };
+ kbcb {
+ nvidia,pins = "kbcb", "kbcd";
+ nvidia,function = "sdio2";
+ };
+ lcsn {
+ nvidia,pins = "lcsn", "ld0", "ld1", "ld2",
+ "ld3", "ld4", "ld5", "ld6", "ld7",
+ "ld8", "ld9", "ld10", "ld11", "ld12",
+ "ld13", "ld14", "ld15", "ld16", "ld17",
+ "ldc", "ldi", "lhp0", "lhp1", "lhp2",
+ "lhs", "lm0", "lm1", "lpp", "lpw0",
+ "lpw1", "lpw2", "lsc0", "lsc1", "lsck",
+ "lsda", "lsdi", "lspi", "lvp0", "lvp1",
+ "lvs";
+ nvidia,function = "displaya";
+ };
+ owc {
+ nvidia,pins = "owc";
+ nvidia,function = "owr";
+ };
+ pmc {
+ nvidia,pins = "pmc";
+ nvidia,function = "pwr_on";
+ };
+ rm {
+ nvidia,pins = "rm";
+ nvidia,function = "i2c1";
+ };
+ sdc {
+ nvidia,pins = "sdc";
+ nvidia,function = "twc";
+ };
+ sdio1 {
+ nvidia,pins = "sdio1";
+ nvidia,function = "sdio1";
+ };
+ slxc {
+ nvidia,pins = "slxc", "slxd";
+ nvidia,function = "spi4";
+ };
+ spdi {
+ nvidia,pins = "spdi", "spdo";
+ nvidia,function = "rsvd2";
+ };
+ spif {
+ nvidia,pins = "spif", "uac";
+ nvidia,function = "rsvd4";
+ };
+ spig {
+ nvidia,pins = "spig", "spih";
+ nvidia,function = "spi2_alt";
+ };
+ uaa {
+ nvidia,pins = "uaa", "uab", "uda";
+ nvidia,function = "ulpi";
+ };
+ uad {
+ nvidia,pins = "uad";
+ nvidia,function = "spdif";
+ };
+ uca {
+ nvidia,pins = "uca", "ucb";
+ nvidia,function = "uartc";
+ };
+ conf_ata {
+ nvidia,pins = "ata", "atb", "atc", "atd", "ate",
+ "cdev1", "cdev2", "dap1", "dap2", "dtf",
+ "gma", "gmb", "gmc", "gmd", "gme",
+ "gpu", "gpu7", "gpv", "i2cp", "pta",
+ "rm", "sdio1", "slxk", "spdo", "uac",
+ "uda";
+ nvidia,pull = <0>;
+ nvidia,tristate = <0>;
+ };
+ conf_ck32 {
+ nvidia,pins = "ck32", "ddrc", "pmca", "pmcb",
+ "pmcc", "pmcd", "pmce", "xm2c", "xm2d";
+ nvidia,pull = <0>;
+ };
+ conf_crtp {
+ nvidia,pins = "crtp", "dap3", "dap4", "dtb",
+ "dtc", "dte", "slxa", "slxc", "slxd",
+ "spdi";
+ nvidia,pull = <0>;
+ nvidia,tristate = <1>;
+ };
+ conf_csus {
+ nvidia,pins = "csus", "spia", "spib", "spid",
+ "spif";
+ nvidia,pull = <1>;
+ nvidia,tristate = <1>;
+ };
+ conf_ddc {
+ nvidia,pins = "ddc", "irrx", "irtx", "kbca",
+ "kbcb", "kbcc", "kbcd", "kbce", "kbcf",
+ "spic", "spig", "uaa", "uab";
+ nvidia,pull = <2>;
+ nvidia,tristate = <0>;
+ };
+ conf_dta {
+ nvidia,pins = "dta", "dtd", "owc", "sdc", "sdd",
+ "spie", "spih", "uad", "uca", "ucb";
+ nvidia,pull = <2>;
+ nvidia,tristate = <1>;
+ };
+ conf_hdint {
+ nvidia,pins = "hdint", "ld0", "ld1", "ld2",
+ "ld3", "ld4", "ld5", "ld6", "ld7",
+ "ld8", "ld9", "ld10", "ld11", "ld12",
+ "ld13", "ld14", "ld15", "ld16", "ld17",
+ "ldc", "ldi", "lhs", "lsc0", "lspi",
+ "lvs", "pmc";
+ nvidia,tristate = <0>;
+ };
+ conf_lc {
+ nvidia,pins = "lc", "ls";
+ nvidia,pull = <2>;
+ };
+ conf_lcsn {
+ nvidia,pins = "lcsn", "lhp0", "lhp1", "lhp2",
+ "lm0", "lm1", "lpp", "lpw0", "lpw1",
+ "lpw2", "lsc1", "lsck", "lsda", "lsdi",
+ "lvp0", "lvp1", "sdb";
+ nvidia,tristate = <1>;
+ };
+ conf_ld17_0 {
+ nvidia,pins = "ld17_0", "ld19_18", "ld21_20",
+ "ld23_22";
+ nvidia,pull = <1>;
+ };
+ };
+ };
};
--
1.8.1.4
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 1/2] tegra20: add pinctrl driver
2013-05-10 18:28 [PATCH v2 1/2] tegra20: add pinctrl driver Lucas Stach
2013-05-10 18:28 ` [PATCH v2 2/2] tegra: paz00: import pinconfig from Linux Lucas Stach
@ 2013-05-10 19:03 ` Alexander Aring
2013-05-11 15:17 ` Sascha Hauer
2013-10-22 15:07 ` Uwe Kleine-König
2 siblings, 1 reply; 6+ messages in thread
From: Alexander Aring @ 2013-05-10 19:03 UTC (permalink / raw)
To: Lucas Stach; +Cc: barebox
Hi Lucas,
On Fri, May 10, 2013 at 08:28:57PM +0200, Lucas Stach wrote:
> This adds a pinctrl driver for the Tegra 20 line of SoCs. It only
> supports the three basic pinconfiguration settings function mux,
> tristate control and pullup/down control.
>
> The driver understands the same devicetree bindings as the Linux one,
> unimplemented pinconfiguration options will be ignored.
>
> Signed-off-by: Lucas Stach <dev@lynxeye.de>
> ---
> v2:
> - use named regs
> - check for return value of request_mem_region
> ---
> arch/arm/dts/tegra20.dtsi | 8 +
> arch/arm/mach-tegra/Kconfig | 1 +
> drivers/pinctrl/Kconfig | 6 +
> drivers/pinctrl/Makefile | 1 +
> drivers/pinctrl/pinctrl-tegra20.c | 346 ++++++++++++++++++++++++++++++++++++++
> 5 files changed, 362 insertions(+)
> create mode 100644 drivers/pinctrl/pinctrl-tegra20.c
>
> diff --git a/arch/arm/dts/tegra20.dtsi b/arch/arm/dts/tegra20.dtsi
> index b7d1e27..f63ead8 100644
> --- a/arch/arm/dts/tegra20.dtsi
> +++ b/arch/arm/dts/tegra20.dtsi
> @@ -34,6 +34,14 @@
> interrupt-controller;
> };
>
> + pinmux: pinmux {
> + compatible = "nvidia,tegra20-pinmux";
> + reg = <0x70000014 0x10 /* Tri-state registers */
> + 0x70000080 0x20 /* Mux registers */
> + 0x700000a0 0x14 /* Pull-up/down registers */
> + 0x70000868 0xa8>; /* Pad control registers */
> + };
> +
> pmc {
> compatible = "nvidia,tegra20-pmc";
> reg = <0x7000e400 0x400>;
> diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig
> index 965e7ab..53ae070 100644
> --- a/arch/arm/mach-tegra/Kconfig
> +++ b/arch/arm/mach-tegra/Kconfig
> @@ -5,6 +5,7 @@ choice
>
> config ARCH_TEGRA_2x_SOC
> bool "Tegra 20"
> + select PINCTRL_TEGRA20
>
> endchoice
>
> diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
> index e6aee50..0b859b8 100644
> --- a/drivers/pinctrl/Kconfig
> +++ b/drivers/pinctrl/Kconfig
> @@ -25,4 +25,10 @@ config PINCTRL_IMX_IOMUX_V3
> help
> This iomux controller is found on i.MX25,35,51,53,6.
>
> +config PINCTRL_TEGRA20
> + select PINCTRL
> + bool "Tegra 20 pinmux"
> + help
> + The pinmux controller found on the Tegra 20 line of SoCs.
> +
> endmenu
> diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
> index e9272d0..169ed18 100644
> --- a/drivers/pinctrl/Makefile
> +++ b/drivers/pinctrl/Makefile
> @@ -2,3 +2,4 @@ obj-$(CONFIG_PINCTRL) += pinctrl.o
> obj-$(CONFIG_PINCTRL_IMX_IOMUX_V1) += imx-iomux-v1.o
> obj-$(CONFIG_PINCTRL_IMX_IOMUX_V2) += imx-iomux-v2.o
> obj-$(CONFIG_PINCTRL_IMX_IOMUX_V3) += imx-iomux-v3.o
> +obj-$(CONFIG_PINCTRL_TEGRA20) += pinctrl-tegra20.o
> diff --git a/drivers/pinctrl/pinctrl-tegra20.c b/drivers/pinctrl/pinctrl-tegra20.c
> new file mode 100644
> index 0000000..053981f
> --- /dev/null
> +++ b/drivers/pinctrl/pinctrl-tegra20.c
> @@ -0,0 +1,346 @@
> +/*
> + * Copyright (C) 2013 Lucas Stach <l.stach@pengutronix.de>
> + *
> + * Partly based on code
> + * Copyright (C) 2011-2012 NVIDIA Corporation <www.nvidia.com>
> + * Copyright (C) 2010 Google, Inc.
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
> + * more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program. If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +/**
> + * @file
> + * @brief Device driver for the Tegra 20 pincontrol hardware module.
> + */
> +
> +#include <common.h>
> +#include <init.h>
> +#include <io.h>
> +#include <malloc.h>
> +#include <pinctrl.h>
> +
> +struct pinctrl_tegra20 {
> + struct {
> + u32 __iomem *tri;
> + u32 __iomem *mux;
> + u32 __iomem *pull;
> + } regs;
> + struct pinctrl_device pinctrl;
> +};
> +
> +struct tegra20_pingroup {
> + const char *name;
> + const char *funcs[4];
> + s16 trictrl_id;
> + s16 muxctrl_id;
> + s16 pullctrl_id;
> +};
> +
> +#define PG(pg_name, f0, f1, f2, f3, tri, mux, pull) \
> + { \
> + .name = #pg_name, \
> + .funcs = { #f0, #f1, #f2, #f3, }, \
> + .trictrl_id = tri, \
> + .muxctrl_id = mux, \
> + .pullctrl_id = pull \
> + }
> +
> +static const struct tegra20_pingroup tegra20_groups[] = {
> + /* name, f0, f1, f2, f3, tri, mux, pull */
> + PG(ata, ide, nand, gmi, rsvd4, 0, 12, 0 ),
> + PG(atb, ide, nand, gmi, sdio4, 1, 8, 1 ),
> + PG(atc, ide, nand, gmi, sdio4, 2, 11, 2 ),
> + PG(atd, ide, nand, gmi, sdio4, 3, 10, 3 ),
> + PG(ate, ide, nand, gmi, rsvd4, 57, 6, 4 ),
> + PG(cdev1, osc, plla_out, pllm_out1, audio_sync, 4, 33, 32 ),
> + PG(cdev2, osc, ahb_clk, apb_clk, pllp_out4, 5, 34, 33 ),
> + PG(crtp, crt, rsvd2, rsvd3, rsvd4, 110, 105, 28 ),
> + PG(csus, pllc_out1, pllp_out2, pllp_out3, vi_sensor_clk, 6, 35, 60 ),
> + PG(dap1, dap1, rsvd2, gmi, sdio2, 7, 42, 5 ),
> + PG(dap2, dap2, twc, rsvd3, gmi, 8, 43, 6 ),
> + PG(dap3, dap3, rsvd2, rsvd3, rsvd4, 9, 44, 7 ),
> + PG(dap4, dap4, rsvd2, gmi, rsvd4, 10, 45, 8 ),
> + PG(ddc, i2c2, rsvd2, rsvd3, rsvd4, 63, 32, 78 ),
> + PG(dta, rsvd1, sdio2, vi, rsvd4, 11, 26, 9 ),
> + PG(dtb, rsvd1, rsvd2, vi, spi1, 12, 27, 10 ),
> + PG(dtc, rsvd1, rsvd2, vi, rsvd4, 13, 29, 11 ),
> + PG(dtd, rsvd1, sdio2, vi, rsvd4, 14, 30, 12 ),
> + PG(dte, rsvd1, rsvd2, vi, spi1, 15, 31, 13 ),
> + PG(dtf, i2c3, rsvd2, vi, rsvd4, 108, 110, 14 ),
> + PG(gma, uarte, spi3, gmi, sdio4, 28, 16, 74 ),
> + PG(gmb, ide, nand, gmi, gmi_int, 61, 46, 75 ),
> + PG(gmc, uartd, spi4, gmi, sflash, 29, 17, 76 ),
> + PG(gmd, rsvd1, nand, gmi, sflash, 62, 47, 77 ),
> + PG(gme, rsvd1, dap5, gmi, sdio4, 32, 48, 44 ),
> + PG(gpu, pwm, uarta, gmi, rsvd4, 16, 50, 26 ),
> + PG(gpu7, rtck, rsvd2, rsvd3, rsvd4, 107, 109, 19 ),
> + PG(gpv, pcie, rsvd2, rsvd3, rsvd4, 17, 49, 15 ),
> + PG(hdint, hdmi, rsvd2, rsvd3, rsvd4, 87, 18, -1 ),
> + PG(i2cp, i2cp, rsvd2, rsvd3, rsvd4, 18, 36, 17 ),
> + PG(irrx, uarta, uartb, gmi, spi4, 20, 41, 43 ),
> + PG(irtx, uarta, uartb, gmi, spi4, 19, 40, 42 ),
> + PG(kbca, kbc, nand, sdio2, emc_test0_dll, 22, 37, 20 ),
> + PG(kbcb, kbc, nand, sdio2, mio, 21, 38, 21 ),
> + PG(kbcc, kbc, nand, trace, emc_test1_dll, 58, 39, 22 ),
> + PG(kbcd, kbc, nand, sdio2, mio, 106, 108, 23 ),
> + PG(kbce, kbc, nand, owr, rsvd4, 26, 14, 65 ),
> + PG(kbcf, kbc, nand, trace, mio, 27, 13, 64 ),
> + PG(lcsn, displaya, displayb, spi3, rsvd4, 95, 70, -1 ),
> + PG(ld0, displaya, displayb, xio, rsvd4, 64, 80, -1 ),
> + PG(ld1, displaya, displayb, xio, rsvd4, 65, 81, -1 ),
> + PG(ld2, displaya, displayb, xio, rsvd4, 66, 82, -1 ),
> + PG(ld3, displaya, displayb, xio, rsvd4, 67, 83, -1 ),
> + PG(ld4, displaya, displayb, xio, rsvd4, 68, 84, -1 ),
> + PG(ld5, displaya, displayb, xio, rsvd4, 69, 85, -1 ),
> + PG(ld6, displaya, displayb, xio, rsvd4, 70, 86, -1 ),
> + PG(ld7, displaya, displayb, xio, rsvd4, 71, 87, -1 ),
> + PG(ld8, displaya, displayb, xio, rsvd4, 72, 88, -1 ),
> + PG(ld9, displaya, displayb, xio, rsvd4, 73, 89, -1 ),
> + PG(ld10, displaya, displayb, xio, rsvd4, 74, 90, -1 ),
> + PG(ld11, displaya, displayb, xio, rsvd4, 75, 91, -1 ),
> + PG(ld12, displaya, displayb, xio, rsvd4, 76, 92, -1 ),
> + PG(ld13, displaya, displayb, xio, rsvd4, 77, 93, -1 ),
> + PG(ld14, displaya, displayb, xio, rsvd4, 78, 94, -1 ),
> + PG(ld15, displaya, displayb, xio, rsvd4, 79, 95, -1 ),
> + PG(ld16, displaya, displayb, xio, rsvd4, 80, 96, -1 ),
> + PG(ld17, displaya, displayb, rsvd3, rsvd4, 81, 97, -1 ),
> + PG(ldc, displaya, displayb, rsvd3, rsvd4, 94, 71, -1 ),
> + PG(ldi, displaya, displayb, rsvd3, rsvd4, 102, 104, -1 ),
> + PG(lhp0, displaya, displayb, rsvd3, rsvd4, 82, 101, -1 ),
> + PG(lhp1, displaya, displayb, rsvd3, rsvd4, 83, 98, -1 ),
> + PG(lhp2, displaya, displayb, rsvd3, rsvd4, 84, 99, -1 ),
> + PG(lhs, displaya, displayb, xio, rsvd4, 103, 75, -1 ),
> + PG(lm0, displaya, displayb, spi3, rsvd4, 88, 77, -1 ),
> + PG(lm1, displaya, displayb, rsvd3, CRT, 89, 78, -1 ),
> + PG(lpp, displaya, displayb, rsvd3, rsvd4, 104, 103, -1 ),
> + PG(lpw0, displaya, displayb, spi3, hdmi, 99, 64, -1 ),
> + PG(lpw1, displaya, displayb, rsvd3, rsvd4, 100, 65, -1 ),
> + PG(lpw2, displaya, displayb, spi3, hdmi, 101, 66, -1 ),
> + PG(lsc0, displaya, displayb, xio, rsvd4, 91, 73, -1 ),
> + PG(lsc1, displaya, displayb, spi3, hdmi, 92, 74, -1 ),
> + PG(lsck, displaya, displayb, spi3, hdmi, 93, 72, -1 ),
> + PG(lsda, displaya, displayb, spi3, hdmi, 97, 68, -1 ),
> + PG(lsdi, displaya, displayb, spi3, rsvd4, 98, 67, -1 ),
> + PG(lspi, displaya, displayb, xio, hdmi, 96, 69, -1 ),
> + PG(lvp0, displaya, displayb, rsvd3, rsvd4, 85, 79, -1 ),
> + PG(lvp1, displaya, displayb, rsvd3, rsvd4, 86, 100, -1 ),
> + PG(lvs, displaya, displayb, xio, rsvd4, 90, 76, -1 ),
> + PG(owc, owr, rsvd2, rsvd3, rsvd4, 31, 20, 79 ),
> + PG(pmc, pwr_on, pwr_intr, rsvd3, rsvd4, 23, 105, -1 ),
> + PG(pta, i2c2, hdmi, gmi, rsvd4, 24, 107, 18 ),
> + PG(rm, i2c1, rsvd2, rsvd3, rsvd4, 25, 7, 16 ),
> + PG(sdb, uarta, pwm, sdio3, spi2, 111, 53, -1 ),
> + PG(sdc, pwm, twc, sdio3, spi3, 33, 54, 62 ),
> + PG(sdd, uarta, pwm, sdio3, spi3, 34, 55, 63 ),
> + PG(sdio1, sdio1, rsvd2, uarte, uarta, 30, 15, 73 ),
> + PG(slxa, pcie, spi4, sdio3, spi2, 36, 19, 27 ),
> + PG(slxc, spdif, spi4, sdio3, spi2, 37, 21, 29 ),
> + PG(slxd, spdif, spi4, sdio3, spi2, 38, 22, 30 ),
> + PG(slxk, pcie, spi4, sdio3, spi2, 39, 23, 31 ),
> + PG(spdi, spdif, rsvd2, i2c1, sdio2, 40, 52, 24 ),
> + PG(spdo, spdif, rsvd2, i2c1, sdio2, 41, 51, 25 ),
> + PG(spia, spi1, spi2, spi3, gmi, 42, 63, 34 ),
> + PG(spib, spi1, spi2, spi3, gmi, 43, 62, 35 ),
> + PG(spic, spi1, spi2, spi3, gmi, 44, 61, 36 ),
> + PG(spid, spi2, spi1, spi2_alt, gmi, 45, 60, 37 ),
> + PG(spie, spi2, spi1, spi2_alt, gmi, 46, 59, 38 ),
> + PG(spif, spi3, spi1, spi2, rsvd4, 47, 58, 39 ),
> + PG(spig, spi3, spi2, spi2_alt, i2c1, 48, 57, 40 ),
> + PG(spih, spi3, spi2, spi2_alt, i2c1, 49, 56, 41 ),
> + PG(uaa, spi3, mipi_hs, uarta, ulpi, 50, 0, 48 ),
> + PG(uab, spi2, mipi_hs, uarta, ulpi, 51, 1, 49 ),
> + PG(uac, owr, rsvd2, rsvd3, rsvd4, 52, 2, 50 ),
> + PG(uad, irda, spdif, uarta, spi4, 53, 3, 51 ),
> + PG(uca, uartc, rsvd2, gmi, rsvd4, 54, 24, 52 ),
> + PG(ucb, uartc, pwm, gmi, rsvd4, 55, 25, 53 ),
> + PG(uda, spi1, rsvd2, uartd, ulpi, 109, 4, 72 ),
> +};
> +
> +static void pinctrl_tegra20_set_func(struct pinctrl_tegra20 *ctrl,
> + int muxctrl_id, int func)
> +{
> + u32 __iomem *regaddr = ctrl->regs.mux;
> + u32 reg;
> + int maskbit;
> +
> + regaddr += muxctrl_id >> 4;
> + maskbit = (muxctrl_id << 1) & 0x1f;
> +
> + reg = readl(regaddr);
> + reg &= ~(0x3 << maskbit);
> + reg |= func << maskbit;
> + writel(reg, regaddr);
> +}
> +
> +static void pinctrl_tegra20_set_pull(struct pinctrl_tegra20 *ctrl,
> + int pullctrl_id, int pull)
> +{
> + u32 __iomem *regaddr = ctrl->regs.pull;
> + u32 reg;
> + int maskbit;
> +
> + regaddr += pullctrl_id >> 4;
> + maskbit = (pullctrl_id << 1) & 0x1f;
> +
> + reg = readl(regaddr);
> + reg &= ~(0x3 << maskbit);
> + reg |= pull << maskbit;
> + writel(reg, regaddr);
> +}
> +
> +static void pinctrl_tegra20_set_tristate(struct pinctrl_tegra20 *ctrl,
> + int trictrl_id, int tristate)
> +{
> + u32 __iomem *regaddr = ctrl->regs.tri;
> + u32 reg;
> + int maskbit;
> +
> + regaddr += trictrl_id >> 5;
> + maskbit = trictrl_id & 0x1f;
> +
> + reg = readl(regaddr);
> + reg &= ~(1 << maskbit);
> + reg |= tristate << maskbit;
> + writel(reg, regaddr);
> +}
> +
> +static int pinctrl_tegra20_set_state(struct pinctrl_device *pdev,
> + struct device_node *np)
> +{
> + struct pinctrl_tegra20 *ctrl =
> + container_of(pdev, struct pinctrl_tegra20, pinctrl);
> + struct device_node *childnode;
> + int pull = -1, tri = -1, i, j, k;
> + const char *pins, *func = NULL;
> + const struct tegra20_pingroup *group;
> +
> + /*
> + * At first look if the node we are pointed at has children,
> + * which we may want to visit.
> + */
> + list_for_each_entry(childnode, &np->children, parent_list)
> + pinctrl_tegra20_set_state(pdev, childnode);
> +
> + /* read relevant state from devicetree */
> + of_property_read_string(np, "nvidia,function", &func);
> + of_property_read_u32_array(np, "nvidia,pull", &pull, 1);
> + of_property_read_u32_array(np, "nvidia,tristate", &tri, 1);
> +
> + /* iterate over all pingroups referenced in the dt node */
> + for (i = 0; ; i++) {
> + if (of_property_read_string_index(np, "nvidia,pins", i, &pins))
> + break;
> +
> + for (j = 0; j < ARRAY_SIZE(tegra20_groups); j++) {
> + if (!strcmp(pins, tegra20_groups[j].name)) {
> + group = &tegra20_groups[j];
> + break;
> + }
> + }
> + /* if no matching pingroup is found bail out */
> + if (j == ARRAY_SIZE(tegra20_groups)) {
> + dev_warn(ctrl->pinctrl.dev,
> + "invalid pingroup %s referenced in node %s\n",
> + pins, np->name);
> + continue;
> + }
> +
> + if (func) {
> + for (k = 0; k < 4; k++) {
> + if (!strcmp(func, group->funcs[k]))
> + break;
> + }
> + if (k < 4)
> + pinctrl_tegra20_set_func(ctrl,
> + group->muxctrl_id, k);
> + else
> + dev_warn(ctrl->pinctrl.dev,
> + "invalid function %s for pingroup %s in node %s\n",
> + func, group->name, np->name);
> + }
> +
> + if (pull >= 0) {
> + if (group->pullctrl_id >= 0)
> + pinctrl_tegra20_set_pull(ctrl,
> + group->pullctrl_id,
> + pull);
> + else
> + dev_warn(ctrl->pinctrl.dev,
> + "pingroup %s in node %s doesn't support pull configuration\n",
> + group->name, np->name);
> + }
> +
> + if (tri >= 0)
> + pinctrl_tegra20_set_tristate(ctrl,
> + group->trictrl_id, tri);
> + }
> +
> + return 0;
> +}
> +
> +static struct pinctrl_ops pinctrl_tegra20_ops = {
> + .set_state = pinctrl_tegra20_set_state,
> +};
> +
> +static int pinctrl_tegra20_probe(struct device_d *dev)
> +{
> + struct pinctrl_tegra20 *ctrl;
> + int i, ret;
> + u32 **regs;
> +
> + ctrl = xzalloc(sizeof(*ctrl));
> +
> + /*
> + * Tegra pincontrol is split out into four independent memory ranges:
> + * tristate control, function mux, pullup/down control, pad control
> + * (from lowest to highest hardware address).
> + * We are only interested in the first three for now.
> + */
> + regs = (u32 **)&ctrl->regs;
> + for (i = 0; i <= 2; i++) {
> + regs[i] = dev_request_mem_region(dev, i);
> + if (!regs[i]) {
> + dev_err(dev, "Could not get iomem region %d\n", i);
Do we need a free(ctrl); here?
Regards
Alex
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 1/2] tegra20: add pinctrl driver
2013-05-10 19:03 ` [PATCH v2 1/2] tegra20: add pinctrl driver Alexander Aring
@ 2013-05-11 15:17 ` Sascha Hauer
2013-05-12 13:48 ` Jean-Christophe PLAGNIOL-VILLARD
0 siblings, 1 reply; 6+ messages in thread
From: Sascha Hauer @ 2013-05-11 15:17 UTC (permalink / raw)
To: Alexander Aring; +Cc: barebox
On Fri, May 10, 2013 at 09:03:10PM +0200, Alexander Aring wrote:
> Hi Lucas,
>
> On Fri, May 10, 2013 at 08:28:57PM +0200, Lucas Stach wrote:
> > This adds a pinctrl driver for the Tegra 20 line of SoCs. It only
> > supports the three basic pinconfiguration settings function mux,
> > tristate control and pullup/down control.
> >
> > The driver understands the same devicetree bindings as the Linux one,
> > unimplemented pinconfiguration options will be ignored.
> >
> > Signed-off-by: Lucas Stach <dev@lynxeye.de>
[...]
> > +
> > +static int pinctrl_tegra20_probe(struct device_d *dev)
> > +{
> > + struct pinctrl_tegra20 *ctrl;
> > + int i, ret;
> > + u32 **regs;
> > +
> > + ctrl = xzalloc(sizeof(*ctrl));
> > +
> > + /*
> > + * Tegra pincontrol is split out into four independent memory ranges:
> > + * tristate control, function mux, pullup/down control, pad control
> > + * (from lowest to highest hardware address).
> > + * We are only interested in the first three for now.
> > + */
> > + regs = (u32 **)&ctrl->regs;
> > + for (i = 0; i <= 2; i++) {
> > + regs[i] = dev_request_mem_region(dev, i);
> > + if (!regs[i]) {
> > + dev_err(dev, "Could not get iomem region %d\n", i);
> Do we need a free(ctrl); here?
To be correct, yes, we would need a free() here.
I've never been very thoroughly with releasing the resources in the
error pathes in the drivers in barebox though and I never felt bad about
it.
The probe calls are called only once for each device and whether or not
we have a few bytes of malloc space more doesn't really matter. Also you
may have noticed that there even is no dev_release_mem_region in barebox
which makes nearly all error pathes wrong in barebox anyway.
And no, I don't want to have -EPROBE_DEFER in barebox.
So I don't really know what to do with the error pathes in driver probe
functions. I don't really care about them, but I also don't feel like
removing the freeing of resources either to reduce the binary size.
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 1/2] tegra20: add pinctrl driver
2013-05-11 15:17 ` Sascha Hauer
@ 2013-05-12 13:48 ` Jean-Christophe PLAGNIOL-VILLARD
0 siblings, 0 replies; 6+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2013-05-12 13:48 UTC (permalink / raw)
To: Sascha Hauer; +Cc: barebox
On 17:17 Sat 11 May , Sascha Hauer wrote:
> On Fri, May 10, 2013 at 09:03:10PM +0200, Alexander Aring wrote:
> > Hi Lucas,
> >
> > On Fri, May 10, 2013 at 08:28:57PM +0200, Lucas Stach wrote:
> > > This adds a pinctrl driver for the Tegra 20 line of SoCs. It only
> > > supports the three basic pinconfiguration settings function mux,
> > > tristate control and pullup/down control.
> > >
> > > The driver understands the same devicetree bindings as the Linux one,
> > > unimplemented pinconfiguration options will be ignored.
> > >
> > > Signed-off-by: Lucas Stach <dev@lynxeye.de>
>
> [...]
>
> > > +
> > > +static int pinctrl_tegra20_probe(struct device_d *dev)
> > > +{
> > > + struct pinctrl_tegra20 *ctrl;
> > > + int i, ret;
> > > + u32 **regs;
> > > +
> > > + ctrl = xzalloc(sizeof(*ctrl));
> > > +
> > > + /*
> > > + * Tegra pincontrol is split out into four independent memory ranges:
> > > + * tristate control, function mux, pullup/down control, pad control
> > > + * (from lowest to highest hardware address).
> > > + * We are only interested in the first three for now.
> > > + */
> > > + regs = (u32 **)&ctrl->regs;
> > > + for (i = 0; i <= 2; i++) {
> > > + regs[i] = dev_request_mem_region(dev, i);
> > > + if (!regs[i]) {
> > > + dev_err(dev, "Could not get iomem region %d\n", i);
> > Do we need a free(ctrl); here?
>
> To be correct, yes, we would need a free() here.
>
> I've never been very thoroughly with releasing the resources in the
> error pathes in the drivers in barebox though and I never felt bad about
> it.
>
> The probe calls are called only once for each device and whether or not
> we have a few bytes of malloc space more doesn't really matter. Also you
> may have noticed that there even is no dev_release_mem_region in barebox
> which makes nearly all error pathes wrong in barebox anyway.
>
> And no, I don't want to have -EPROBE_DEFER in barebox.
this can be problematic for some pinctrl as they will present late
that's why we introduce it in the kernel
>
> So I don't really know what to do with the error pathes in driver probe
> functions. I don't really care about them, but I also don't feel like
> removing the freeing of resources either to reduce the binary size.
>
> Sascha
>
>
> --
> Pengutronix e.K. | |
> Industrial Linux Solutions | http://www.pengutronix.de/ |
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
> Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
>
> _______________________________________________
> barebox mailing list
> barebox@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/barebox
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 1/2] tegra20: add pinctrl driver
2013-05-10 18:28 [PATCH v2 1/2] tegra20: add pinctrl driver Lucas Stach
2013-05-10 18:28 ` [PATCH v2 2/2] tegra: paz00: import pinconfig from Linux Lucas Stach
2013-05-10 19:03 ` [PATCH v2 1/2] tegra20: add pinctrl driver Alexander Aring
@ 2013-10-22 15:07 ` Uwe Kleine-König
2 siblings, 0 replies; 6+ messages in thread
From: Uwe Kleine-König @ 2013-10-22 15:07 UTC (permalink / raw)
To: Lucas Stach; +Cc: barebox
Hello Lucas,
On Fri, May 10, 2013 at 08:28:57PM +0200, Lucas Stach wrote:
> diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
> index e6aee50..0b859b8 100644
> --- a/drivers/pinctrl/Kconfig
> +++ b/drivers/pinctrl/Kconfig
> @@ -25,4 +25,10 @@ config PINCTRL_IMX_IOMUX_V3
> help
> This iomux controller is found on i.MX25,35,51,53,6.
>
> +config PINCTRL_TEGRA20
> + select PINCTRL
> + bool "Tegra 20 pinmux"
Now that I tried barebox' master on an i.MX28 I was presented with the
question to enable PINCTRL_TEGRA20 or not during oldconfig. Maybe don't
make this user-selectable? (The other pinctrl driver are affected by the
same "issue".)
> + help
> + The pinmux controller found on the Tegra 20 line of SoCs.
> +
> endmenu
--
Pengutronix e.K. | Uwe Kleine-König |
Industrial Linux Solutions | http://www.pengutronix.de/ |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2013-10-22 15:07 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-05-10 18:28 [PATCH v2 1/2] tegra20: add pinctrl driver Lucas Stach
2013-05-10 18:28 ` [PATCH v2 2/2] tegra: paz00: import pinconfig from Linux Lucas Stach
2013-05-10 19:03 ` [PATCH v2 1/2] tegra20: add pinctrl driver Alexander Aring
2013-05-11 15:17 ` Sascha Hauer
2013-05-12 13:48 ` Jean-Christophe PLAGNIOL-VILLARD
2013-10-22 15:07 ` Uwe Kleine-König
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox