mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [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