Skip to contentSkip to conversation

tegra20: add pinctrl driver

PATCH Superseded Lucas Stach 3 participants 6 messages May 6, 2013 – May 8, 2013

Subsystems (3)

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore
#0 lore raw

PATCH 1/2 tegra20: add pinctrl driver

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.

---
 arch/arm/dts/tegra20.dtsi         |   8 +
 drivers/pinctrl/Kconfig           |   6 +
 drivers/pinctrl/Makefile          |   1 +
 drivers/pinctrl/pinctrl-tegra20.c | 336 ++++++++++++++++++++++++++++++++++++++
 4 files changed, 351 insertions(+)
 create mode 100644 drivers/pinctrl/pinctrl-tegra20.c
arch/arm/dts/tegra20.dtsi +8 -0
index b7d1e27..f63ead8 100644
@@ -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>;
drivers/pinctrl/Kconfig +6 -0
index e6aee50..0b859b8 100644
@@ -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
drivers/pinctrl/Makefile +1 -0
index e9272d0..169ed18 100644
@@ -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
drivers/pinctrl/pinctrl-tegra20.c new file +336 -0

336 lines not on this page · raw message

Signature · 7 lines
1.8.1.4


_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox
#1 lore raw

PATCH 2/2 tegra: paz00: import pinconfig from Linux

---
 arch/arm/dts/tegra20-paz00.dts | 216 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 216 insertions(+)
arch/arm/dts/tegra20-paz00.dts +216 -0
index 09ccb8b..e8486aa 100644
@@ -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>;
+			};
+		};
+	};
 };
Signature · 7 lines
1.8.1.4


_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox
#2 lore raw
In reply to Lucas Stach
Quoted 21 lines · Lucas Stach

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.

---
 arch/arm/dts/tegra20.dtsi         |   8 +
 drivers/pinctrl/Kconfig           |   6 +
 drivers/pinctrl/Makefile          |   1 +
 drivers/pinctrl/pinctrl-tegra20.c | 336 ++++++++++++++++++++++++++++++++++++++
 4 files changed, 351 insertions(+)
 create mode 100644 drivers/pinctrl/pinctrl-tegra20.c
arch/arm/dts/tegra20.dtsi +0 -0
index b7d1e27..f63ead8 100644

arch/arm/dts/tegra20.dtsi line 42

Quoted 9 lines
arch/arm/dts/tegra20.dtsi +6 -0
@@ -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 */

tab here

Quoted 10 lines
arch/arm/dts/tegra20.dtsi +2 -0
+	};
+
 	pmc {
 		compatible = "nvidia,tegra20-pmc";
 		reg = <0x7000e400 0x400>;
drivers/pinctrl/Kconfig +0 -0
index e6aee50..0b859b8 100644

drivers/pinctrl/Kconfig config PINCTRL_IMX_IOMUX_V3 · line 32

Quoted 8 lines
drivers/pinctrl/Kconfig +5 -0
@@ -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.

pinctrl will be mandatory on tegra

Quoted 170 lines
drivers/pinctrl/Kconfig +1 -0
+
 endmenu
drivers/pinctrl/Makefile +1 -0
index e9272d0..169ed18 100644
@@ -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
drivers/pinctrl/pinctrl-tegra20.c new file +153 -0
new file mode 100644
index 0000000..44a4a0c
@@ -0,0 +1,336 @@
+/*
+ * Copyright (C) 2013 Lucas Stach <[email protected]>
+ *
+ * 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 <pinctrl.h>
+#include <malloc.h>
+
+struct pinctrl_tegra20 {
+	void __iomem *regs[3];
+	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 ),

drivers/pinctrl/pinctrl-tegra20.c line 163

Quoted 10 lines
drivers/pinctrl/pinctrl-tegra20.c new file +10 -0
+	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 ),
+};

really ugly blob but it's like tegra define so not choice

Quoted 121 lines
drivers/pinctrl/pinctrl-tegra20.c new file +121 -0
+
+static void pinctrl_tegra20_set_func(struct pinctrl_tegra20 *ctrl,
+				     int muxctrl_id, int func)
+{
+	u32 *regaddr = ctrl->regs[1];
+	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 *regaddr = ctrl->regs[2];
+	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 *regaddr = ctrl->regs[0];
+	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;

drivers/pinctrl/pinctrl-tegra20.c line 294

Quoted 10 lines
drivers/pinctrl/pinctrl-tegra20.c new file +10 -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 = 0;

no need the init of ret

drivers/pinctrl/pinctrl-tegra20.c line 306

Quoted 12 lines
drivers/pinctrl/pinctrl-tegra20.c new file +12 -0
+
+	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.
+	 */
+	for (i = 0; i <= 2; i++) {
+		ctrl->regs[i] = dev_request_mem_region(dev, i);
+	}

drop {}

but use a specific name will simplify debug

and make the code easier

drivers/pinctrl/pinctrl-tegra20.c line 313

Quoted 7 lines
drivers/pinctrl/pinctrl-tegra20.c new file +7 -0
+
+	ctrl->pinctrl.dev = dev;
+	ctrl->pinctrl.ops = &pinctrl_tegra20_ops;
+
+	ret = pinctrl_register(&ctrl->pinctrl);
+	if (ret)
+		free(ctrl);

report an error message

drivers/pinctrl/pinctrl-tegra20.c line 314

Quoted 1 line
drivers/pinctrl/pinctrl-tegra20.c new file +1 -0
+

we sould handle probe defer too

Quoted 30 lines
drivers/pinctrl/pinctrl-tegra20.c new file +22 -0
+	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);
Signature · 7 lines
1.8.1.4


_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox

_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox

#3 lore raw
Quoted 10 lines · Jean-Christophe PLAGNIOL-VILLARD

drivers/pinctrl/pinctrl-tegra20.c line 294

Quoted 9 lines
drivers/pinctrl/pinctrl-tegra20.c new file +9 -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 = 0;

no need the init of ret

Quoted 11 lines

drivers/pinctrl/pinctrl-tegra20.c line 305

Quoted 11 lines
drivers/pinctrl/pinctrl-tegra20.c new file +11 -0
+
+	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.
+	 */
+	for (i = 0; i <= 2; i++) {
+		ctrl->regs[i] = dev_request_mem_region(dev, i);

The return values of dev_request_mem_region should be checked for new drivers. I know 98% of the code currently does not do this and it was a mistake. The above may fail if regions overlap or there are other bugs in the devicetree. Having this silently fail means that the actual register accesses do a NULL pointer deref later.

Quoted 4 lines

Review

Quoted 1 line
(quoted diff) +1 -0
+	}

drop {}

but use a specific name will simplify debug

I don't think this should be mandatory.

Quoted 10 lines

and make the code easier

drivers/pinctrl/pinctrl-tegra20.c line 313

Quoted 7 lines
drivers/pinctrl/pinctrl-tegra20.c new file +7 -0
+
+	ctrl->pinctrl.dev = dev;
+	ctrl->pinctrl.ops = &pinctrl_tegra20_ops;
+
+	ret = pinctrl_register(&ctrl->pinctrl);
+	if (ret)
+		free(ctrl);

report an error message

The core will answer with an error message here. There is no need to litter the code with error messages which only add to the binary size. The above may fail for a developer but really should not fail for a user. A developer has enough information with the probe functions error code.

Sascha

Signature · 9 lines
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
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox
#4 lore raw
Quoted 20 lines · Sascha Hauer
Quoted 19 lines · Jean-Christophe PLAGNIOL-VILLARD

drivers/pinctrl/pinctrl-tegra20.c line 294

Quoted 9 lines
drivers/pinctrl/pinctrl-tegra20.c new file +9 -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 = 0;

no need the init of ret

Quoted 9 lines
drivers/pinctrl/pinctrl-tegra20.c new file +9 -0
+
+	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.
+	 */
Quoted 8 lines
Quoted 2 lines

drivers/pinctrl/pinctrl-tegra20.c line 305

Quoted 2 lines
drivers/pinctrl/pinctrl-tegra20.c new file +2 -0
+	for (i = 0; i <= 2; i++) {
+		ctrl->regs[i] = dev_request_mem_region(dev, i);

The return values of dev_request_mem_region should be checked for new drivers. I know 98% of the code currently does not do this and it was a mistake. The above may fail if regions overlap or there are other bugs in the devicetree. Having this silently fail means that the actual register accesses do a NULL pointer deref later.

why not simply put a BUG in the request_mem

Quoted 7 lines
Quoted 5 lines

Review

Quoted 2 lines
(quoted diff) +1 -0
+	}

drop {}

but use a specific name will simplify debug

I don't think this should be mandatory.

the issue is that a number can be easly endup to a hiden typo (no compile error) where a ttypo in the name will no compile.

Quoted 12 lines
Quoted 11 lines

and make the code easier

drivers/pinctrl/pinctrl-tegra20.c line 313

Quoted 7 lines
drivers/pinctrl/pinctrl-tegra20.c new file +7 -0
+
+	ctrl->pinctrl.dev = dev;
+	ctrl->pinctrl.ops = &pinctrl_tegra20_ops;
+
+	ret = pinctrl_register(&ctrl->pinctrl);
+	if (ret)
+		free(ctrl);

report an error message

Quoted 4 lines

The core will answer with an error message here. There is no need to litter the code with error messages which only add to the binary size. The above may fail for a developer but really should not fail for a user. A developer has enough information with the probe functions error code.

pinctrl_register print no error message

it's good to known why we failled no just that the probe return -Exxx

and this will not impact the binary size if we put a dev_warn or dev_debug

as we can drop them with the printk level

_______________________________________________
barebox mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox

#5 lore raw
In reply to Jean-Christophe PLAGNIOL-VILLARD
Quoted 25 lines · Jean-Christophe PLAGNIOL-VILLARD
Quoted 24 lines · Lucas Stach

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.

---
 arch/arm/dts/tegra20.dtsi         |   8 +
 drivers/pinctrl/Kconfig           |   6 +
 drivers/pinctrl/Makefile          |   1 +
 drivers/pinctrl/pinctrl-tegra20.c | 336 ++++++++++++++++++++++++++++++++++++++
 4 files changed, 351 insertions(+)
 create mode 100644 drivers/pinctrl/pinctrl-tegra20.c
arch/arm/dts/tegra20.dtsi +0 -0
index b7d1e27..f63ead8 100644
@@ -34,6 +34,14 @@
 		interrupt-controller;
 	};
 
Quoted 7 lines

arch/arm/dts/tegra20.dtsi line 42

Quoted 6 lines
arch/arm/dts/tegra20.dtsi +6 -0
+	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 */

tab here

This is done to align under the lines above. I wouldn't do it in my code, but it's perfectly fine to do it.

Quoted 13 lines
Quoted 13 lines
arch/arm/dts/tegra20.dtsi +2 -0
+	};
+
 	pmc {
 		compatible = "nvidia,tegra20-pmc";
 		reg = <0x7000e400 0x400>;
drivers/pinctrl/Kconfig +0 -0
index e6aee50..0b859b8 100644
@@ -25,4 +25,10 @@ config PINCTRL_IMX_IOMUX_V3
 	help
 	  This iomux controller is found on i.MX25,35,51,53,6.
 
Quoted 6 lines

drivers/pinctrl/Kconfig config PINCTRL_IMX_IOMUX_V3 · line 32

Quoted 5 lines
drivers/pinctrl/Kconfig +5 -0
+config PINCTRL_TEGRA20
+	select PINCTRL
+	bool "Tegra 20 pinmux"
+	help
+	  The pinmux controller found on the Tegra 20 line of SoCs.

pinctrl will be mandatory on tegra

It will, yes, but no need to do it now. There can well be some time to test the driver before it becomes mandatory.

Sascha

Signature · 9 lines
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
[email protected]
http://lists.infradead.org/mailman/listinfo/barebox