pinctrl: tegra: add Tegra3 driver
Signed-off-by: Lucas Stach <dev@lynxeye.de> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
This commit is contained in:
parent
e61f9e458d
commit
f09394ab1a
|
@ -48,6 +48,7 @@ config ARCH_TEGRA_2x_SOC
|
|||
|
||||
config ARCH_TEGRA_3x_SOC
|
||||
bool
|
||||
select PINCTRL_TEGRA30
|
||||
|
||||
menu "select Tegra boards to be built"
|
||||
|
||||
|
|
|
@ -33,3 +33,9 @@ config PINCTRL_TEGRA20
|
|||
bool
|
||||
help
|
||||
The pinmux controller found on the Tegra 20 line of SoCs.
|
||||
|
||||
config PINCTRL_TEGRA30
|
||||
select PINCTRL
|
||||
bool
|
||||
help
|
||||
The pinmux controller found on the Tegra 30 line of SoCs.
|
||||
|
|
|
@ -4,3 +4,4 @@ obj-$(CONFIG_PINCTRL_IMX_IOMUX_V2) += imx-iomux-v2.o
|
|||
obj-$(CONFIG_PINCTRL_IMX_IOMUX_V3) += imx-iomux-v3.o
|
||||
obj-$(CONFIG_PINCTRL_SINGLE) += pinctrl-single.o
|
||||
obj-$(CONFIG_PINCTRL_TEGRA20) += pinctrl-tegra20.o
|
||||
obj-$(CONFIG_PINCTRL_TEGRA30) += pinctrl-tegra30.o
|
||||
|
|
|
@ -0,0 +1,503 @@
|
|||
/*
|
||||
* Copyright (C) 2014 Lucas Stach <l.stach@pengutronix.de>
|
||||
*
|
||||
* Partly based on code
|
||||
* Copyright (C) 2011-2012, NVIDIA CORPORATION.
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <init.h>
|
||||
#include <io.h>
|
||||
#include <malloc.h>
|
||||
#include <pinctrl.h>
|
||||
|
||||
struct pinctrl_tegra30 {
|
||||
struct {
|
||||
u32 __iomem *ctrl;
|
||||
u32 __iomem *mux;
|
||||
} regs;
|
||||
struct pinctrl_device pinctrl;
|
||||
};
|
||||
|
||||
struct tegra30_pingroup {
|
||||
const char *name;
|
||||
const char *funcs[4];
|
||||
u16 reg;
|
||||
};
|
||||
|
||||
#define PG(pg_name, f0, f1, f2, f3, offset) \
|
||||
{ \
|
||||
.name = #pg_name, \
|
||||
.funcs = { #f0, #f1, #f2, #f3, }, \
|
||||
.reg = offset \
|
||||
}
|
||||
|
||||
static const struct tegra30_pingroup tegra30_groups[] = {
|
||||
/* name, f0, f1, f2, f3, reg */
|
||||
PG(clk_32k_out_pa0, blink, rsvd2, rsvd3, rsvd4, 0x31c),
|
||||
PG(uart3_cts_n_pa1, uartc, rsvd2, gmi, rsvd4, 0x17c),
|
||||
PG(dap2_fs_pa2, i2s1, hda, rsvd3, gmi, 0x358),
|
||||
PG(dap2_sclk_pa3, i2s1, hda, rsvd3, gmi, 0x364),
|
||||
PG(dap2_din_pa4, i2s1, hda, rsvd3, gmi, 0x35c),
|
||||
PG(dap2_dout_pa5, i2s1, hda, rsvd3, gmi, 0x360),
|
||||
PG(sdmmc3_clk_pa6, uarta, pwm2, sdmmc3, spi3, 0x390),
|
||||
PG(sdmmc3_cmd_pa7, uarta, pwm3, sdmmc3, spi2, 0x394),
|
||||
PG(gmi_a17_pb0, uartd, spi4, gmi, dtv, 0x234),
|
||||
PG(gmi_a18_pb1, uartd, spi4, gmi, dtv, 0x238),
|
||||
PG(lcd_pwr0_pb2, displaya, displayb, spi5, hdcp, 0x090),
|
||||
PG(lcd_pclk_pb3, displaya, displayb, rsvd3, rsvd4, 0x094),
|
||||
PG(sdmmc3_dat3_pb4, rsvd1, pwm0, sdmmc3, spi3, 0x3a4),
|
||||
PG(sdmmc3_dat2_pb5, rsvd1, pwm1, sdmmc3, spi3, 0x3a0),
|
||||
PG(sdmmc3_dat1_pb6, rsvd1, rsvd2, sdmmc3, spi3, 0x39c),
|
||||
PG(sdmmc3_dat0_pb7, rsvd1, rsvd2, sdmmc3, spi3, 0x398),
|
||||
PG(uart3_rts_n_pc0, uartc, pwm0, gmi, rsvd4, 0x180),
|
||||
PG(lcd_pwr1_pc1, displaya, displayb, rsvd3, rsvd4, 0x070),
|
||||
PG(uart2_txd_pc2, uartb, spdif, uarta, spi4, 0x168),
|
||||
PG(uart2_rxd_pc3, uartb, spdif, uarta, spi4, 0x164),
|
||||
PG(gen1_i2c_scl_pc4, i2c1, rsvd2, rsvd3, rsvd4, 0x1a4),
|
||||
PG(gen1_i2c_sda_pc5, i2c1, rsvd2, rsvd3, rsvd4, 0x1a0),
|
||||
PG(lcd_pwr2_pc6, displaya, displayb, spi5, hdcp, 0x074),
|
||||
PG(gmi_wp_n_pc7, rsvd1, nand, gmi, gmi_alt, 0x1c0),
|
||||
PG(sdmmc3_dat5_pd0, pwm0, spi4, sdmmc3, spi2, 0x3ac),
|
||||
PG(sdmmc3_dat4_pd1, pwm1, spi4, sdmmc3, spi2, 0x3a8),
|
||||
PG(lcd_dc1_pd2, displaya, displayb, rsvd3, rsvd4, 0x10c),
|
||||
PG(sdmmc3_dat6_pd3, spdif, spi4, sdmmc3, spi2, 0x3b0),
|
||||
PG(sdmmc3_dat7_pd4, spdif, spi4, sdmmc3, spi2, 0x3b4),
|
||||
PG(vi_d1_pd5, ddr, sdmmc2, vi, rsvd4, 0x128),
|
||||
PG(vi_vsync_pd6, ddr, rsvd2, vi, rsvd4, 0x15c),
|
||||
PG(vi_hsync_pd7, ddr, rsvd2, vi, rsvd4, 0x160),
|
||||
PG(lcd_d0_pe0, displaya, displayb, rsvd3, rsvd4, 0x0a4),
|
||||
PG(lcd_d1_pe1, displaya, displayb, rsvd3, rsvd4, 0x0a8),
|
||||
PG(lcd_d2_pe2, displaya, displayb, rsvd3, rsvd4, 0x0ac),
|
||||
PG(lcd_d3_pe3, displaya, displayb, rsvd3, rsvd4, 0x0b0),
|
||||
PG(lcd_d4_pe4, displaya, displayb, rsvd3, rsvd4, 0x0b4),
|
||||
PG(lcd_d5_pe5, displaya, displayb, rsvd3, rsvd4, 0x0b8),
|
||||
PG(lcd_d6_pe6, displaya, displayb, rsvd3, rsvd4, 0x0bc),
|
||||
PG(lcd_d7_pe7, displaya, displayb, rsvd3, rsvd4, 0x0c0),
|
||||
PG(lcd_d8_pf0, displaya, displayb, rsvd3, rsvd4, 0x0c4),
|
||||
PG(lcd_d9_pf1, displaya, displayb, rsvd3, rsvd4, 0x0c8),
|
||||
PG(lcd_d10_pf2, displaya, displayb, rsvd3, rsvd4, 0x0cc),
|
||||
PG(lcd_d11_pf3, displaya, displayb, rsvd3, rsvd4, 0x0d0),
|
||||
PG(lcd_d12_pf4, displaya, displayb, rsvd3, rsvd4, 0x0d4),
|
||||
PG(lcd_d13_pf5, displaya, displayb, rsvd3, rsvd4, 0x0d8),
|
||||
PG(lcd_d14_pf6, displaya, displayb, rsvd3, rsvd4, 0x0dc),
|
||||
PG(lcd_d15_pf7, displaya, displayb, rsvd3, rsvd4, 0x0e0),
|
||||
PG(gmi_ad0_pg0, rsvd1, nand, gmi, rsvd4, 0x1f0),
|
||||
PG(gmi_ad1_pg1, rsvd1, nand, gmi, rsvd4, 0x1f4),
|
||||
PG(gmi_ad2_pg2, rsvd1, nand, gmi, rsvd4, 0x1f8),
|
||||
PG(gmi_ad3_pg3, rsvd1, nand, gmi, rsvd4, 0x1fc),
|
||||
PG(gmi_ad4_pg4, rsvd1, nand, gmi, rsvd4, 0x200),
|
||||
PG(gmi_ad5_pg5, rsvd1, nand, gmi, rsvd4, 0x204),
|
||||
PG(gmi_ad6_pg6, rsvd1, nand, gmi, rsvd4, 0x208),
|
||||
PG(gmi_ad7_pg7, rsvd1, nand, gmi, rsvd4, 0x20c),
|
||||
PG(gmi_ad8_ph0, pwm0, nand, gmi, rsvd4, 0x210),
|
||||
PG(gmi_ad9_ph1, pwm1, nand, gmi, rsvd4, 0x214),
|
||||
PG(gmi_ad10_ph2, pwm2, nand, gmi, rsvd4, 0x218),
|
||||
PG(gmi_ad11_ph3, pwm3, nand, gmi, rsvd4, 0x21c),
|
||||
PG(gmi_ad12_ph4, rsvd1, nand, gmi, rsvd4, 0x220),
|
||||
PG(gmi_ad13_ph5, rsvd1, nand, gmi, rsvd4, 0x224),
|
||||
PG(gmi_ad14_ph6, rsvd1, nand, gmi, rsvd4, 0x228),
|
||||
PG(gmi_ad15_ph7, rsvd1, nand, gmi, rsvd4, 0x22c),
|
||||
PG(gmi_wr_n_pi0, rsvd1, nand, gmi, rsvd4, 0x240),
|
||||
PG(gmi_oe_n_pi1, rsvd1, nand, gmi, rsvd4, 0x244),
|
||||
PG(gmi_dqs_pi2, rsvd1, nand, gmi, rsvd4, 0x248),
|
||||
PG(gmi_cs6_n_pi3, nand, nand_alt, gmi, sata, 0x1e8),
|
||||
PG(gmi_rst_n_pi4, nand, nand_alt, gmi, rsvd4, 0x24c),
|
||||
PG(gmi_iordy_pi5, rsvd1, nand, gmi, rsvd4, 0x1c4),
|
||||
PG(gmi_cs7_n_pi6, nand, nand_alt, gmi, gmi_alt, 0x1ec),
|
||||
PG(gmi_wait_pi7, rsvd1, nand, gmi, rsvd4, 0x1c8),
|
||||
PG(gmi_cs0_n_pj0, rsvd1, nand, gmi, dtv, 0x1d4),
|
||||
PG(lcd_de_pj1, displaya, displayb, rsvd3, rsvd4, 0x098),
|
||||
PG(gmi_cs1_n_pj2, rsvd1, nand, gmi, dtv, 0x1d8),
|
||||
PG(lcd_hsync_pj3, displaya, displayb, rsvd3, rsvd4, 0x09c),
|
||||
PG(lcd_vsync_pj4, displaya, displayb, rsvd3, rsvd4, 0x0a0),
|
||||
PG(uart2_cts_n_pj5, uarta, uartb, gmi, spi4, 0x170),
|
||||
PG(uart2_rts_n_pj6, uarta, uartb, gmi, spi4, 0x16c),
|
||||
PG(gmi_a16_pj7, uartd, spi4, gmi, gmi_alt, 0x230),
|
||||
PG(gmi_adv_n_pk0, rsvd1, nand, gmi, rsvd4, 0x1cc),
|
||||
PG(gmi_clk_pk1, rsvd1, nand, gmi, rsvd4, 0x1d0),
|
||||
PG(gmi_cs4_n_pk2, rsvd1, nand, gmi, rsvd4, 0x1e4),
|
||||
PG(gmi_cs2_n_pk3, rsvd1, nand, gmi, rsvd4, 0x1dc),
|
||||
PG(gmi_cs3_n_pk4, rsvd1, nand, gmi, gmi_alt, 0x1e0),
|
||||
PG(spdif_out_pk5, spdif, rsvd2, i2c1, sdmmc2, 0x354),
|
||||
PG(spdif_in_pk6, spdif, hda, i2c1, sdmmc2, 0x350),
|
||||
PG(gmi_a19_pk7, uartd, spi4, gmi, rsvd4, 0x23c),
|
||||
PG(vi_d2_pl0, ddr, sdmmc2, vi, rsvd4, 0x12c),
|
||||
PG(vi_d3_pl1, ddr, sdmmc2, vi, rsvd4, 0x130),
|
||||
PG(vi_d4_pl2, ddr, sdmmc2, vi, rsvd4, 0x134),
|
||||
PG(vi_d5_pl3, ddr, sdmmc2, vi, rsvd4, 0x138),
|
||||
PG(vi_d6_pl4, ddr, sdmmc2, vi, rsvd4, 0x13c),
|
||||
PG(vi_d7_pl5, ddr, sdmmc2, vi, rsvd4, 0x140),
|
||||
PG(vi_d8_pl6, ddr, sdmmc2, vi, rsvd4, 0x144),
|
||||
PG(vi_d9_pl7, ddr, sdmmc2, vi, rsvd4, 0x148),
|
||||
PG(lcd_d16_pm0, displaya, displayb, rsvd3, rsvd4, 0x0e4),
|
||||
PG(lcd_d17_pm1, displaya, displayb, rsvd3, rsvd4, 0x0e8),
|
||||
PG(lcd_d18_pm2, displaya, displayb, rsvd3, rsvd4, 0x0ec),
|
||||
PG(lcd_d19_pm3, displaya, displayb, rsvd3, rsvd4, 0x0f0),
|
||||
PG(lcd_d20_pm4, displaya, displayb, rsvd3, rsvd4, 0x0f4),
|
||||
PG(lcd_d21_pm5, displaya, displayb, rsvd3, rsvd4, 0x0f8),
|
||||
PG(lcd_d22_pm6, displaya, displayb, rsvd3, rsvd4, 0x0fc),
|
||||
PG(lcd_d23_pm7, displaya, displayb, rsvd3, rsvd4, 0x100),
|
||||
PG(dap1_fs_pn0, i2s0, hda, gmi, sdmmc2, 0x338),
|
||||
PG(dap1_din_pn1, i2s0, hda, gmi, sdmmc2, 0x33c),
|
||||
PG(dap1_dout_pn2, i2s0, hda, gmi, sdmmc2, 0x340),
|
||||
PG(dap1_sclk_pn3, i2s0, hda, gmi, sdmmc2, 0x344),
|
||||
PG(lcd_cs0_n_pn4, displaya, displayb, spi5, rsvd4, 0x084),
|
||||
PG(lcd_sdout_pn5, displaya, displayb, spi5, hdcp, 0x07c),
|
||||
PG(lcd_dc0_pn6, displaya, displayb, rsvd3, rsvd4, 0x088),
|
||||
PG(hdmi_int_pn7, hdmi, rsvd2, rsvd3, rsvd4, 0x110),
|
||||
PG(ulpi_data7_po0, spi2, hsi, uarta, ulpi, 0x01c),
|
||||
PG(ulpi_data0_po1, spi3, hsi, uarta, ulpi, 0x000),
|
||||
PG(ulpi_data1_po2, spi3, hsi, uarta, ulpi, 0x004),
|
||||
PG(ulpi_data2_po3, spi3, hsi, uarta, ulpi, 0x008),
|
||||
PG(ulpi_data3_po4, spi3, hsi, uarta, ulpi, 0x00c),
|
||||
PG(ulpi_data4_po5, spi2, hsi, uarta, ulpi, 0x010),
|
||||
PG(ulpi_data5_po6, spi2, hsi, uarta, ulpi, 0x014),
|
||||
PG(ulpi_data6_po7, spi2, hsi, uarta, ulpi, 0x018),
|
||||
PG(dap3_fs_pp0, i2s2, rsvd2, displaya, displayb, 0x030),
|
||||
PG(dap3_din_pp1, i2s2, rsvd2, displaya, displayb, 0x034),
|
||||
PG(dap3_dout_pp2, i2s2, rsvd2, displaya, displayb, 0x038),
|
||||
PG(dap3_sclk_pp3, i2s2, rsvd2, displaya, displayb, 0x03c),
|
||||
PG(dap4_fs_pp4, i2s3, rsvd2, gmi, rsvd4, 0x1a8),
|
||||
PG(dap4_din_pp5, i2s3, rsvd2, gmi, rsvd4, 0x1ac),
|
||||
PG(dap4_dout_pp6, i2s3, rsvd2, gmi, rsvd4, 0x1b0),
|
||||
PG(dap4_sclk_pp7, i2s3, rsvd2, gmi, rsvd4, 0x1b4),
|
||||
PG(kb_col0_pq0, kbc, nand, trace, test, 0x2fc),
|
||||
PG(kb_col1_pq1, kbc, nand, trace, test, 0x300),
|
||||
PG(kb_col2_pq2, kbc, nand, trace, rsvd4, 0x304),
|
||||
PG(kb_col3_pq3, kbc, nand, trace, rsvd4, 0x308),
|
||||
PG(kb_col4_pq4, kbc, nand, trace, rsvd4, 0x30c),
|
||||
PG(kb_col5_pq5, kbc, nand, trace, rsvd4, 0x310),
|
||||
PG(kb_col6_pq6, kbc, nand, trace, mio, 0x314),
|
||||
PG(kb_col7_pq7, kbc, nand, trace, mio, 0x318),
|
||||
PG(kb_row0_pr0, kbc, nand, rsvd3, rsvd4, 0x2bc),
|
||||
PG(kb_row1_pr1, kbc, nand, rsvd3, rsvd4, 0x2c0),
|
||||
PG(kb_row2_pr2, kbc, nand, rsvd3, rsvd4, 0x2c4),
|
||||
PG(kb_row3_pr3, kbc, nand, rsvd3, invalid, 0x2c8),
|
||||
PG(kb_row4_pr4, kbc, nand, trace, rsvd4, 0x2cc),
|
||||
PG(kb_row5_pr5, kbc, nand, trace, owr, 0x2d0),
|
||||
PG(kb_row6_pr6, kbc, nand, sdmmc2, mio, 0x2d4),
|
||||
PG(kb_row7_pr7, kbc, nand, sdmmc2, mio, 0x2d8),
|
||||
PG(kb_row8_ps0, kbc, nand, sdmmc2, mio, 0x2dc),
|
||||
PG(kb_row9_ps1, kbc, nand, sdmmc2, mio, 0x2e0),
|
||||
PG(kb_row10_ps2, kbc, nand, sdmmc2, mio, 0x2e4),
|
||||
PG(kb_row11_ps3, kbc, nand, sdmmc2, mio, 0x2e8),
|
||||
PG(kb_row12_ps4, kbc, nand, sdmmc2, mio, 0x2ec),
|
||||
PG(kb_row13_ps5, kbc, nand, sdmmc2, mio, 0x2f0),
|
||||
PG(kb_row14_ps6, kbc, nand, sdmmc2, mio, 0x2f4),
|
||||
PG(kb_row15_ps7, kbc, nand, sdmmc2, mio, 0x2f8),
|
||||
PG(vi_pclk_pt0, rsvd1, sdmmc2, vi, rsvd4, 0x154),
|
||||
PG(vi_mclk_pt1, vi, vi_alt1, vi_alt2, vi_alt3, 0x158),
|
||||
PG(vi_d10_pt2, ddr, rsvd2, vi, rsvd4, 0x14c),
|
||||
PG(vi_d11_pt3, ddr, rsvd2, vi, rsvd4, 0x150),
|
||||
PG(vi_d0_pt4, ddr, rsvd2, vi, rsvd4, 0x124),
|
||||
PG(gen2_i2c_scl_pt5, i2c2, hdcp, gmi, rsvd4, 0x250),
|
||||
PG(gen2_i2c_sda_pt6, i2c2, hdcp, gmi, rsvd4, 0x254),
|
||||
PG(sdmmc4_cmd_pt7, i2c3, nand, gmi, sdmmc4, 0x25c),
|
||||
PG(pu0, owr, uarta, gmi, rsvd4, 0x184),
|
||||
PG(pu1, rsvd1, uarta, gmi, rsvd4, 0x188),
|
||||
PG(pu2, rsvd1, uarta, gmi, rsvd4, 0x18c),
|
||||
PG(pu3, pwm0, uarta, gmi, rsvd4, 0x190),
|
||||
PG(pu4, pwm1, uarta, gmi, rsvd4, 0x194),
|
||||
PG(pu5, pwm2, uarta, gmi, rsvd4, 0x198),
|
||||
PG(pu6, pwm3, uarta, gmi, rsvd4, 0x19c),
|
||||
PG(jtag_rtck_pu7, rtck, rsvd2, rsvd3, rsvd4, 0x2b0),
|
||||
PG(pv0, rsvd1, rsvd2, rsvd3, rsvd4, 0x040),
|
||||
PG(pv1, rsvd1, rsvd2, rsvd3, rsvd4, 0x044),
|
||||
PG(pv2, owr, rsvd2, rsvd3, rsvd4, 0x060),
|
||||
PG(pv3, clk_12m_out, rsvd2, rsvd3, rsvd4, 0x064),
|
||||
PG(ddc_scl_pv4, i2c4, rsvd2, rsvd3, rsvd4, 0x114),
|
||||
PG(ddc_sda_pv5, i2c4, rsvd2, rsvd3, rsvd4, 0x118),
|
||||
PG(crt_hsync_pv6, crt, rsvd2, rsvd3, rsvd4, 0x11c),
|
||||
PG(crt_vsync_pv7, crt, rsvd2, rsvd3, rsvd4, 0x120),
|
||||
PG(lcd_cs1_n_pw0, displaya, displayb, spi5, rsvd4, 0x104),
|
||||
PG(lcd_m1_pw1, displaya, displayb, rsvd3, rsvd4, 0x108),
|
||||
PG(spi2_cs1_n_pw2, spi3, spi2, spi2_alt, i2c1, 0x388),
|
||||
PG(spi2_cs2_n_pw3, spi3, spi2, spi2_alt, i2c1, 0x38c),
|
||||
PG(clk1_out_pw4, extperiph1, rsvd2, rsvd3, rsvd4, 0x34c),
|
||||
PG(clk2_out_pw5, extperiph2, rsvd2, rsvd3, rsvd4, 0x068),
|
||||
PG(uart3_txd_pw6, uartc, rsvd2, gmi, rsvd4, 0x174),
|
||||
PG(uart3_rxd_pw7, uartc, rsvd2, gmi, rsvd4, 0x178),
|
||||
PG(spi2_mosi_px0, spi6, spi2, spi3, gmi, 0x368),
|
||||
PG(spi2_miso_px1, spi6, spi2, spi3, gmi, 0x36c),
|
||||
PG(spi2_sck_px2, spi6, spi2, spi3, gmi, 0x374),
|
||||
PG(spi2_cs0_n_px3, spi6, spi2, spi3, gmi, 0x370),
|
||||
PG(spi1_mosi_px4, spi2, spi1, spi2_alt, gmi, 0x378),
|
||||
PG(spi1_sck_px5, spi2, spi1, spi2_alt, gmi, 0x37c),
|
||||
PG(spi1_cs0_n_px6, spi2, spi1, spi2_alt, gmi, 0x380),
|
||||
PG(spi1_miso_px7, spi3, spi1, spi2_alt, rsvd4, 0x384),
|
||||
PG(ulpi_clk_py0, spi1, rsvd2, uartd, ulpi, 0x020),
|
||||
PG(ulpi_dir_py1, spi1, rsvd2, uartd, ulpi, 0x024),
|
||||
PG(ulpi_nxt_py2, spi1, rsvd2, uartd, ulpi, 0x028),
|
||||
PG(ulpi_stp_py3, spi1, rsvd2, uartd, ulpi, 0x02c),
|
||||
PG(sdmmc1_dat3_py4, sdmmc1, rsvd2, uarte, uarta, 0x050),
|
||||
PG(sdmmc1_dat2_py5, sdmmc1, rsvd2, uarte, uarta, 0x054),
|
||||
PG(sdmmc1_dat1_py6, sdmmc1, rsvd2, uarte, uarta, 0x058),
|
||||
PG(sdmmc1_dat0_py7, sdmmc1, rsvd2, uarte, uarta, 0x05c),
|
||||
PG(sdmmc1_clk_pz0, sdmmc1, rsvd2, rsvd3, uarta, 0x048),
|
||||
PG(sdmmc1_cmd_pz1, sdmmc1, rsvd2, rsvd3, uarta, 0x04c),
|
||||
PG(lcd_sdin_pz2, displaya, displayb, spi5, rsvd4, 0x078),
|
||||
PG(lcd_wr_n_pz3, displaya, displayb, spi5, hdcp, 0x080),
|
||||
PG(lcd_sck_pz4, displaya, displayb, spi5, hdcp, 0x08c),
|
||||
PG(sys_clk_req_pz5, sysclk, rsvd2, rsvd3, rsvd4, 0x320),
|
||||
PG(pwr_i2c_scl_pz6, i2cpwr, rsvd2, rsvd3, rsvd4, 0x2b4),
|
||||
PG(pwr_i2c_sda_pz7, i2cpwr, rsvd2, rsvd3, rsvd4, 0x2b8),
|
||||
PG(sdmmc4_dat0_paa0, uarte, spi3, gmi, sdmmc4, 0x260),
|
||||
PG(sdmmc4_dat1_paa1, uarte, spi3, gmi, sdmmc4, 0x264),
|
||||
PG(sdmmc4_dat2_paa2, uarte, spi3, gmi, sdmmc4, 0x268),
|
||||
PG(sdmmc4_dat3_paa3, uarte, spi3, gmi, sdmmc4, 0x26c),
|
||||
PG(sdmmc4_dat4_paa4, i2c3, i2s4, gmi, sdmmc4, 0x270),
|
||||
PG(sdmmc4_dat5_paa5, vgp3, i2s4, gmi, sdmmc4, 0x274),
|
||||
PG(sdmmc4_dat6_paa6, vgp4, i2s4, gmi, sdmmc4, 0x278),
|
||||
PG(sdmmc4_dat7_paa7, vgp5, i2s4, gmi, sdmmc4, 0x27c),
|
||||
PG(pbb0, i2s4, rsvd2, rsvd3, sdmmc4, 0x28c),
|
||||
PG(cam_i2c_scl_pbb1, vgp1, i2c3, rsvd3, sdmmc4, 0x290),
|
||||
PG(cam_i2c_sda_pbb2, vgp2, i2c3, rsvd3, sdmmc4, 0x294),
|
||||
PG(pbb3, vgp3, displaya, displayb, sdmmc4, 0x298),
|
||||
PG(pbb4, vgp4, displaya, displayb, sdmmc4, 0x29c),
|
||||
PG(pbb5, vgp5, displaya, displayb, sdmmc4, 0x2a0),
|
||||
PG(pbb6, vgp6, displaya, displayb, sdmmc4, 0x2a4),
|
||||
PG(pbb7, i2s4, rsvd2, rsvd3, sdmmc4, 0x2a8),
|
||||
PG(cam_mclk_pcc0, vi, vi_alt1, vi_alt3, sdmmc4, 0x284),
|
||||
PG(pcc1, i2s4, rsvd2, rsvd3, sdmmc4, 0x288),
|
||||
PG(pcc2, i2s4, rsvd2, rsvd3, rsvd4, 0x2ac),
|
||||
PG(sdmmc4_rst_n_pcc3, vgp6, rsvd2, rsvd3, sdmmc4, 0x280),
|
||||
PG(sdmmc4_clk_pcc4, invalid, nand, gmi, sdmmc4, 0x258),
|
||||
PG(clk2_req_pcc5, dap, rsvd2, rsvd3, rsvd4, 0x06c),
|
||||
PG(pex_l2_rst_n_pcc6, pcie, hda, rsvd3, rsvd4, 0x3d8),
|
||||
PG(pex_l2_clkreq_n_pcc7, pcie, hda, rsvd3, rsvd4, 0x3dc),
|
||||
PG(pex_l0_prsnt_n_pdd0, pcie, hda, rsvd3, rsvd4, 0x3b8),
|
||||
PG(pex_l0_rst_n_pdd1, pcie, hda, rsvd3, rsvd4, 0x3bc),
|
||||
PG(pex_l0_clkreq_n_pdd2, pcie, hda, rsvd3, rsvd4, 0x3c0),
|
||||
PG(pex_wake_n_pdd3, pcie, hda, rsvd3, rsvd4, 0x3c4),
|
||||
PG(pex_l1_prsnt_n_pdd4, pcie, hda, rsvd3, rsvd4, 0x3c8),
|
||||
PG(pex_l1_rst_n_pdd5, pcie, hda, rsvd3, rsvd4, 0x3cc),
|
||||
PG(pex_l1_clkreq_n_pdd6, pcie, hda, rsvd3, rsvd4, 0x3d0),
|
||||
PG(pex_l2_prsnt_n_pdd7, pcie, hda, rsvd3, rsvd4, 0x3d4),
|
||||
PG(clk3_out_pee0, extperiph3, rsvd2, rsvd3, rsvd4, 0x1b8),
|
||||
PG(clk3_req_pee1, dev3, rsvd2, rsvd3, rsvd4, 0x1bc),
|
||||
PG(clk1_req_pee2, dap, hda, rsvd3, rsvd4, 0x348),
|
||||
PG(hdmi_cec_pee3, cec, rsvd2, rsvd3, rsvd4, 0x3e0),
|
||||
PG(clk_32k_in, clk_32k_in, rsvd2, rsvd3, rsvd4, 0x330),
|
||||
PG(core_pwr_req, core_pwr_req, rsvd2, rsvd3, rsvd4, 0x324),
|
||||
PG(cpu_pwr_req, cpu_pwr_req, rsvd2, rsvd3, rsvd4, 0x328),
|
||||
PG(owr, owr, cec, rsvd3, rsvd4, 0x334),
|
||||
PG(pwr_int_n, pwr_int_n, rsvd2, rsvd3, rsvd4, 0x32c),
|
||||
};
|
||||
|
||||
static void pinctrl_tegra30_set_func(struct pinctrl_tegra30 *ctrl,
|
||||
u32 reg, int func)
|
||||
{
|
||||
u32 __iomem *regaddr = ctrl->regs.mux + (reg >> 2);
|
||||
u32 val;
|
||||
|
||||
val = readl(regaddr);
|
||||
val &= ~(0x3);
|
||||
val |= func;
|
||||
writel(val, regaddr);
|
||||
}
|
||||
|
||||
static void pinctrl_tegra30_set_pull(struct pinctrl_tegra30 *ctrl,
|
||||
u32 reg, int pull)
|
||||
{
|
||||
u32 __iomem *regaddr = ctrl->regs.mux + (reg >> 2);
|
||||
u32 val;
|
||||
|
||||
val = readl(regaddr);
|
||||
val &= ~(0x3 << 2);
|
||||
val |= pull << 2;
|
||||
writel(val, regaddr);
|
||||
}
|
||||
|
||||
static void pinctrl_tegra30_set_input(struct pinctrl_tegra30 *ctrl,
|
||||
u32 reg, int input)
|
||||
{
|
||||
u32 __iomem *regaddr = ctrl->regs.mux + (reg >> 2);
|
||||
u32 val;
|
||||
|
||||
val = readl(regaddr);
|
||||
val &= ~(1 << 5);
|
||||
val |= input << 5;
|
||||
writel(val, regaddr);
|
||||
}
|
||||
|
||||
static void pinctrl_tegra30_set_tristate(struct pinctrl_tegra30 *ctrl,
|
||||
u32 reg, int tristate)
|
||||
{
|
||||
u32 __iomem *regaddr = ctrl->regs.mux + (reg >> 2);
|
||||
u32 val;
|
||||
|
||||
val = readl(regaddr);
|
||||
val &= ~(1 << 4);
|
||||
val |= tristate << 4;
|
||||
writel(val, regaddr);
|
||||
}
|
||||
|
||||
static void pinctrl_tegra30_set_opendrain(struct pinctrl_tegra30 *ctrl,
|
||||
u32 reg, int opendrain)
|
||||
{
|
||||
u32 __iomem *regaddr = ctrl->regs.mux + (reg >> 2);
|
||||
u32 val;
|
||||
|
||||
val = readl(regaddr);
|
||||
val &= ~(1 << 6);
|
||||
val |= opendrain << 6;
|
||||
writel(val, regaddr);
|
||||
}
|
||||
|
||||
static void pinctrl_tegra30_set_ioreset(struct pinctrl_tegra30 *ctrl,
|
||||
u32 reg, int ioreset)
|
||||
{
|
||||
u32 __iomem *regaddr = ctrl->regs.mux + (reg >> 2);
|
||||
u32 val;
|
||||
|
||||
val = readl(regaddr);
|
||||
val &= ~(1 << 8);
|
||||
val |= ioreset << 8;
|
||||
writel(val, regaddr);
|
||||
}
|
||||
|
||||
static int pinctrl_tegra30_set_state(struct pinctrl_device *pdev,
|
||||
struct device_node *np)
|
||||
{
|
||||
struct pinctrl_tegra30 *ctrl =
|
||||
container_of(pdev, struct pinctrl_tegra30, pinctrl);
|
||||
struct device_node *childnode;
|
||||
int pull = -1, tri = -1, in = -1, od = -1, ior = -1, i, j, k;
|
||||
const char *pins, *func = NULL;
|
||||
const struct tegra30_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_tegra30_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);
|
||||
of_property_read_u32_array(np, "nvidia,enable-input", &in, 1);
|
||||
of_property_read_u32_array(np, "nvidia,open-drain", &od, 1);
|
||||
of_property_read_u32_array(np, "nvidia,io-reset", &ior, 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(tegra30_groups); j++) {
|
||||
if (!strcmp(pins, tegra30_groups[j].name)) {
|
||||
group = &tegra30_groups[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* if no matching pingroup is found bail out */
|
||||
if (j == ARRAY_SIZE(tegra30_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_tegra30_set_func(ctrl, group->reg, 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)
|
||||
pinctrl_tegra30_set_pull(ctrl, group->reg, pull);
|
||||
|
||||
if (in >= 0)
|
||||
pinctrl_tegra30_set_input(ctrl, group->reg, in);
|
||||
|
||||
if (tri >= 0)
|
||||
pinctrl_tegra30_set_tristate(ctrl, group->reg, tri);
|
||||
|
||||
if (od >= 0)
|
||||
pinctrl_tegra30_set_opendrain(ctrl, group->reg, od);
|
||||
|
||||
if (ior >= 0)
|
||||
pinctrl_tegra30_set_ioreset(ctrl, group->reg, ior);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct pinctrl_ops pinctrl_tegra30_ops = {
|
||||
.set_state = pinctrl_tegra30_set_state,
|
||||
};
|
||||
|
||||
static int pinctrl_tegra30_probe(struct device_d *dev)
|
||||
{
|
||||
struct pinctrl_tegra30 *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 <= 1; 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_tegra30_ops;
|
||||
|
||||
ret = pinctrl_register(&ctrl->pinctrl);
|
||||
if (ret)
|
||||
free(ctrl);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static __maybe_unused struct of_device_id pinctrl_tegra30_dt_ids[] = {
|
||||
{
|
||||
.compatible = "nvidia,tegra30-pinmux",
|
||||
}, {
|
||||
/* sentinel */
|
||||
}
|
||||
};
|
||||
|
||||
static struct driver_d pinctrl_tegra30_driver = {
|
||||
.name = "pinctrl-tegra30",
|
||||
.probe = pinctrl_tegra30_probe,
|
||||
.of_compatible = DRV_OF_COMPAT(pinctrl_tegra30_dt_ids),
|
||||
};
|
||||
|
||||
static int pinctrl_tegra30_init(void)
|
||||
{
|
||||
return platform_driver_register(&pinctrl_tegra30_driver);
|
||||
}
|
||||
postcore_initcall(pinctrl_tegra30_init);
|
Loading…
Reference in New Issue