summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2014-11-05 15:47:39 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2014-11-05 15:47:39 +0100
commit7b4cc54579f12cc6c9586e8c21e729dd220e7f45 (patch)
tree85adc78e0eb782f805113b2b48dd07be6555e532
parent254b64520b9a729da496cd8bf637d080de7af5a1 (diff)
parentc202b7c8d9e66082853ac1b131ddcedf53e9ca99 (diff)
downloadbarebox-7b4cc54579f12cc6c9586e8c21e729dd220e7f45.tar.gz
barebox-7b4cc54579f12cc6c9586e8c21e729dd220e7f45.tar.xz
Merge branch 'for-next/tegra'
-rw-r--r--arch/arm/Kconfig1
-rw-r--r--arch/arm/boards/nvidia-beaver/board.c26
-rw-r--r--arch/arm/boards/nvidia-jetson-tk1/Makefile2
-rw-r--r--arch/arm/boards/nvidia-jetson-tk1/board.c61
-rw-r--r--arch/arm/boards/toradex-colibri-t20/Makefile1
-rw-r--r--arch/arm/boards/toradex-colibri-t20/board.c29
-rw-r--r--arch/arm/configs/tegra_v7_defconfig10
-rw-r--r--arch/arm/dts/tegra124-jetson-tk1.dts1825
-rw-r--r--arch/arm/dts/tegra124.dtsi9
-rw-r--r--arch/arm/dts/tegra20-colibri-iris.dts4
-rw-r--r--arch/arm/dts/tegra30-beaver.dts13
-rw-r--r--arch/arm/dts/tegra30.dtsi892
-rw-r--r--arch/arm/mach-tegra/Kconfig35
-rw-r--r--arch/arm/mach-tegra/include/mach/lowlevel.h45
-rw-r--r--arch/arm/mach-tegra/include/mach/tegra-powergate.h93
-rw-r--r--arch/arm/mach-tegra/include/mach/tegra20-car.h2
-rw-r--r--arch/arm/mach-tegra/include/mach/tegra20-pmc.h9
-rw-r--r--arch/arm/mach-tegra/include/mach/tegra30-car.h2
-rw-r--r--arch/arm/mach-tegra/tegra20-pmc.c171
-rw-r--r--arch/arm/mach-tegra/tegra20.c41
-rw-r--r--arch/mips/mach-malta/pci.c4
-rw-r--r--commands/lspci.c25
-rw-r--r--common/reset_source.c1
-rw-r--r--drivers/Kconfig1
-rw-r--r--drivers/Makefile1
-rw-r--r--drivers/clk/tegra/clk-pll.c287
-rw-r--r--drivers/clk/tegra/clk-tegra124.c45
-rw-r--r--drivers/clk/tegra/clk-tegra20.c10
-rw-r--r--drivers/clk/tegra/clk-tegra30.c43
-rw-r--r--drivers/clk/tegra/clk.h13
-rw-r--r--drivers/i2c/busses/i2c-tegra.c2
-rw-r--r--drivers/net/Kconfig8
-rw-r--r--drivers/net/Makefile1
-rw-r--r--drivers/net/rtl8169.c578
-rw-r--r--drivers/of/Kconfig1
-rw-r--r--drivers/of/address.c68
-rw-r--r--drivers/pci/Kconfig7
-rw-r--r--drivers/pci/Makefile1
-rw-r--r--drivers/pci/bus.c3
-rw-r--r--drivers/pci/pci-tegra.c1305
-rw-r--r--drivers/pci/pci.c276
-rw-r--r--drivers/phy/Kconfig18
-rw-r--r--drivers/phy/Makefile5
-rw-r--r--drivers/phy/phy-core.c318
-rw-r--r--drivers/pinctrl/Kconfig8
-rw-r--r--drivers/pinctrl/Makefile1
-rw-r--r--drivers/pinctrl/pinctrl-tegra-xusb.c519
-rw-r--r--drivers/pinctrl/pinctrl-tegra20.c8
-rw-r--r--drivers/pinctrl/pinctrl-tegra30.c8
-rw-r--r--drivers/serial/serial_ns16550.c12
-rw-r--r--include/linux/pci.h9
-rw-r--r--include/linux/pci_regs.h28
-rw-r--r--include/linux/phy/phy.h240
-rw-r--r--include/of_address.h57
-rw-r--r--include/reset_source.h1
55 files changed, 4241 insertions, 2942 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 3c9b81ab06..2a00e5ef38 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -198,6 +198,7 @@ config ARCH_TEGRA
bool "NVIDIA Tegra"
select CPU_V7
select HAS_DEBUG_LL
+ select HW_HAS_PCI
select COMMON_CLK
select COMMON_CLK_OF_PROVIDER
select CLKDEV_LOOKUP
diff --git a/arch/arm/boards/nvidia-beaver/board.c b/arch/arm/boards/nvidia-beaver/board.c
index e87594d5b7..d270301ab3 100644
--- a/arch/arm/boards/nvidia-beaver/board.c
+++ b/arch/arm/boards/nvidia-beaver/board.c
@@ -15,10 +15,12 @@
*/
#include <common.h>
-#include <init.h>
+#include <dt-bindings/gpio/tegra-gpio.h>
+#include <gpio.h>
#include <i2c/i2c.h>
+#include <init.h>
-static int nvidia_beaver_devices_init(void)
+static int nvidia_beaver_fs_init(void)
{
struct i2c_client client;
u8 data;
@@ -33,6 +35,24 @@ static int nvidia_beaver_devices_init(void)
data = 0x65;
i2c_write_reg(&client, 0x32, &data, 1);
+ /* TPS659110: LDO1_REG = 1.05v, ACTIVE to PEX */
+ data = 0x15;
+ i2c_write_reg(&client, 0x30, &data, 1);
+
+ /* enable SYS_3V3_PEXS */
+ gpio_direction_output(TEGRA_GPIO(L, 7), 1);
+
+ return 0;
+}
+fs_initcall(nvidia_beaver_fs_init);
+
+static int nvidia_beaver_device_init(void)
+{
+ if (!of_machine_is_compatible("nvidia,beaver"))
+ return 0;
+
+ barebox_set_hostname("beaver");
+
return 0;
}
-device_initcall(nvidia_beaver_devices_init);
+device_initcall(nvidia_beaver_device_init);
diff --git a/arch/arm/boards/nvidia-jetson-tk1/Makefile b/arch/arm/boards/nvidia-jetson-tk1/Makefile
index f1e46206f8..16b203f9f3 100644
--- a/arch/arm/boards/nvidia-jetson-tk1/Makefile
+++ b/arch/arm/boards/nvidia-jetson-tk1/Makefile
@@ -3,5 +3,5 @@ CFLAGS_pbl-entry.o := \
-fno-tree-switch-conversion -fno-jump-tables
soc := tegra124
lwl-y += entry.o
-#obj-y += board.o
+obj-y += board.o
extra-y += jetson-tk1-2gb-emmc.bct
diff --git a/arch/arm/boards/nvidia-jetson-tk1/board.c b/arch/arm/boards/nvidia-jetson-tk1/board.c
new file mode 100644
index 0000000000..564e6a0aa1
--- /dev/null
+++ b/arch/arm/boards/nvidia-jetson-tk1/board.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2014 Lucas Stach <l.stach@pengutronix.de>
+ *
+ * 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 <dt-bindings/gpio/tegra-gpio.h>
+#include <gpio.h>
+#include <i2c/i2c.h>
+#include <init.h>
+
+#define AS3722_SD_VOLTAGE(n) (0x00 + (n))
+#define AS3722_GPIO_CONTROL(n) (0x08 + (n))
+#define AS3722_GPIO_CONTROL_MODE_OUTPUT_VDDH (1 << 0)
+#define AS3722_GPIO_SIGNAL_OUT 0x20
+#define AS3722_SD_CONTROL 0x4d
+
+static int nvidia_jetson_tk1_fs_init(void)
+{
+ struct i2c_client client;
+ u8 data;
+
+ if (!of_machine_is_compatible("nvidia,jetson-tk1"))
+ return 0;
+
+ client.adapter = i2c_get_adapter(4);
+ client.addr = 0x40;
+
+ /* AS3722: enable SD4 and set voltage to 1.05v */
+ i2c_read_reg(&client, AS3722_SD_CONTROL, &data, 1);
+ data |= 1 << 4;
+ i2c_write_reg(&client, AS3722_SD_CONTROL, &data, 1);
+
+ data = 0x24;
+ i2c_write_reg(&client, AS3722_SD_VOLTAGE(4), &data, 1);
+
+ return 0;
+}
+fs_initcall(nvidia_jetson_tk1_fs_init);
+
+static int nvidia_jetson_tk1_device_init(void)
+{
+ if (!of_machine_is_compatible("nvidia,jetson-tk1"))
+ return 0;
+
+ barebox_set_hostname("jetson-tk1");
+
+ return 0;
+}
+device_initcall(nvidia_jetson_tk1_device_init);
diff --git a/arch/arm/boards/toradex-colibri-t20/Makefile b/arch/arm/boards/toradex-colibri-t20/Makefile
index 1f767328fa..d0347f2382 100644
--- a/arch/arm/boards/toradex-colibri-t20/Makefile
+++ b/arch/arm/boards/toradex-colibri-t20/Makefile
@@ -3,6 +3,7 @@ CFLAGS_pbl-entry.o := \
-fno-tree-switch-conversion -fno-jump-tables
soc := tegra20
lwl-y += entry.o
+obj-y += board.o
extra-y += colibri-t20_256_hsmmc.bct colibri-t20_256_v11_nand.bct \
colibri-t20_256_v12_nand.bct colibri-t20_512_hsmmc.bct \
colibri-t20_512_v11_nand.bct colibri-t20_512_v12_nand.bct \ No newline at end of file
diff --git a/arch/arm/boards/toradex-colibri-t20/board.c b/arch/arm/boards/toradex-colibri-t20/board.c
new file mode 100644
index 0000000000..706198105c
--- /dev/null
+++ b/arch/arm/boards/toradex-colibri-t20/board.c
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2014 Lucas Stach <l.stach@pengutronix.de>
+ *
+ * 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>
+
+static int toradex_colibri_t20_device_init(void)
+{
+ if (!of_machine_is_compatible("toradex,colibri_t20-512"))
+ return 0;
+
+ barebox_set_hostname("colibri-t20");
+
+ return 0;
+}
+device_initcall(toradex_colibri_t20_device_init);
diff --git a/arch/arm/configs/tegra_v7_defconfig b/arch/arm/configs/tegra_v7_defconfig
index 22f5765a3b..47e594ba68 100644
--- a/arch/arm/configs/tegra_v7_defconfig
+++ b/arch/arm/configs/tegra_v7_defconfig
@@ -16,6 +16,7 @@ CONFIG_AUTO_COMPLETE=y
CONFIG_MENU=y
CONFIG_BLSPEC=y
CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y
+CONFIG_RESET_SOURCE=y
CONFIG_LONGHELP=y
CONFIG_CMD_IOMEM=y
CONFIG_CMD_MEMINFO=y
@@ -27,16 +28,25 @@ CONFIG_CMD_RESET=y
CONFIG_CMD_EXPORT=y
CONFIG_CMD_LOADENV=y
CONFIG_CMD_SAVEENV=y
+CONFIG_CMD_DHCP=y
+CONFIG_CMD_MIITOOL=y
+CONFIG_CMD_PING=y
CONFIG_CMD_EDIT=y
CONFIG_CMD_TIMEOUT=y
CONFIG_CMD_CLK=y
CONFIG_CMD_DETECT=y
CONFIG_CMD_GPIO=y
CONFIG_CMD_OFTREE=y
+CONFIG_NET=y
+CONFIG_OF_BAREBOX_DRIVERS=y
CONFIG_DRIVER_SERIAL_NS16550=y
+CONFIG_DRIVER_NET_RTL8169=y
CONFIG_MCI=y
CONFIG_MCI_MMC_BOOT_PARTITIONS=y
CONFIG_MCI_TEGRA=y
+CONFIG_PCI_TEGRA=y
CONFIG_FS_EXT4=y
+CONFIG_FS_TFTP=y
+CONFIG_FS_NFS=y
CONFIG_FS_FAT=y
CONFIG_FS_FAT_LFN=y
diff --git a/arch/arm/dts/tegra124-jetson-tk1.dts b/arch/arm/dts/tegra124-jetson-tk1.dts
index 16082c0bda..26f405ca3d 100644
--- a/arch/arm/dts/tegra124-jetson-tk1.dts
+++ b/arch/arm/dts/tegra124-jetson-tk1.dts
@@ -1,1828 +1,17 @@
-/dts-v1/;
-
-#include <dt-bindings/input/input.h>
+#include <arm/tegra124-jetson-tk1.dts>
#include "tegra124.dtsi"
/ {
- model = "NVIDIA Tegra124 Jetson TK1";
- compatible = "nvidia,jetson-tk1", "nvidia,tegra124";
-
- aliases {
- rtc0 = "/i2c@0,7000d000/pmic@40";
- rtc1 = "/rtc@0,7000e000";
- };
-
- memory {
- reg = <0x0 0x80000000 0x0 0x80000000>;
- };
-
- host1x@0,50000000 {
- hdmi@0,54280000 {
- status = "okay";
-
- hdmi-supply = <&vdd_5v0_hdmi>;
- pll-supply = <&vdd_hdmi_pll>;
- vdd-supply = <&vdd_3v3_hdmi>;
-
- nvidia,ddc-i2c-bus = <&hdmi_ddc>;
- nvidia,hpd-gpio =
- <&gpio TEGRA_GPIO(N, 7) GPIO_ACTIVE_HIGH>;
- };
- };
-
- pinmux: pinmux@0,70000868 {
- pinctrl-names = "default";
- pinctrl-0 = <&state_default>;
-
- state_default: pinmux {
- clk_32k_out_pa0 {
- nvidia,pins = "clk_32k_out_pa0";
- nvidia,function = "soc";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- uart3_cts_n_pa1 {
- nvidia,pins = "uart3_cts_n_pa1";
- nvidia,function = "uartc";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- dap2_fs_pa2 {
- nvidia,pins = "dap2_fs_pa2";
- nvidia,function = "i2s1";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- dap2_sclk_pa3 {
- nvidia,pins = "dap2_sclk_pa3";
- nvidia,function = "i2s1";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- dap2_din_pa4 {
- nvidia,pins = "dap2_din_pa4";
- nvidia,function = "i2s1";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- dap2_dout_pa5 {
- nvidia,pins = "dap2_dout_pa5";
- nvidia,function = "i2s1";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- sdmmc3_clk_pa6 {
- nvidia,pins = "sdmmc3_clk_pa6";
- nvidia,function = "sdmmc3";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- sdmmc3_cmd_pa7 {
- nvidia,pins = "sdmmc3_cmd_pa7";
- nvidia,function = "sdmmc3";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- pb0 {
- nvidia,pins = "pb0";
- nvidia,function = "uartd";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- pb1 {
- nvidia,pins = "pb1";
- nvidia,function = "uartd";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- sdmmc3_dat3_pb4 {
- nvidia,pins = "sdmmc3_dat3_pb4";
- nvidia,function = "sdmmc3";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- sdmmc3_dat2_pb5 {
- nvidia,pins = "sdmmc3_dat2_pb5";
- nvidia,function = "sdmmc3";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- sdmmc3_dat1_pb6 {
- nvidia,pins = "sdmmc3_dat1_pb6";
- nvidia,function = "sdmmc3";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- sdmmc3_dat0_pb7 {
- nvidia,pins = "sdmmc3_dat0_pb7";
- nvidia,function = "sdmmc3";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- uart3_rts_n_pc0 {
- nvidia,pins = "uart3_rts_n_pc0";
- nvidia,function = "uartc";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- uart2_txd_pc2 {
- nvidia,pins = "uart2_txd_pc2";
- nvidia,function = "irda";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- uart2_rxd_pc3 {
- nvidia,pins = "uart2_rxd_pc3";
- nvidia,function = "irda";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- gen1_i2c_scl_pc4 {
- nvidia,pins = "gen1_i2c_scl_pc4";
- nvidia,function = "i2c1";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- nvidia,open-drain = <TEGRA_PIN_ENABLE>;
- };
- gen1_i2c_sda_pc5 {
- nvidia,pins = "gen1_i2c_sda_pc5";
- nvidia,function = "i2c1";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- nvidia,open-drain = <TEGRA_PIN_ENABLE>;
- };
- pc7 {
- nvidia,pins = "pc7";
- nvidia,function = "rsvd1";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- pg0 {
- nvidia,pins = "pg0";
- nvidia,function = "rsvd1";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- pg1 {
- nvidia,pins = "pg1";
- nvidia,function = "rsvd1";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- pg2 {
- nvidia,pins = "pg2";
- nvidia,function = "rsvd1";
- nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- pg3 {
- nvidia,pins = "pg3";
- nvidia,function = "rsvd1";
- nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- pg4 {
- nvidia,pins = "pg4";
- nvidia,function = "spi4";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- pg5 {
- nvidia,pins = "pg5";
- nvidia,function = "spi4";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- pg6 {
- nvidia,pins = "pg6";
- nvidia,function = "spi4";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- pg7 {
- nvidia,pins = "pg7";
- nvidia,function = "spi4";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- ph0 {
- nvidia,pins = "ph0";
- nvidia,function = "gmi";
- nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
- nvidia,tristate = <TEGRA_PIN_ENABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- ph1 {
- nvidia,pins = "ph1";
- nvidia,function = "pwm1";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- ph2 {
- nvidia,pins = "ph2";
- nvidia,function = "gmi";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- ph3 {
- nvidia,pins = "ph3";
- nvidia,function = "gmi";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- ph4 {
- nvidia,pins = "ph4";
- nvidia,function = "rsvd2";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- ph5 {
- nvidia,pins = "ph5";
- nvidia,function = "rsvd2";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- ph6 {
- nvidia,pins = "ph6";
- nvidia,function = "gmi";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- ph7 {
- nvidia,pins = "ph7";
- nvidia,function = "gmi";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- pi0 {
- nvidia,pins = "pi0";
- nvidia,function = "rsvd1";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- pi1 {
- nvidia,pins = "pi1";
- nvidia,function = "rsvd1";
- nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
- nvidia,tristate = <TEGRA_PIN_ENABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- pi2 {
- nvidia,pins = "pi2";
- nvidia,function = "rsvd4";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- pi3 {
- nvidia,pins = "pi3";
- nvidia,function = "spi4";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- pi4 {
- nvidia,pins = "pi4";
- nvidia,function = "gmi";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- pi5 {
- nvidia,pins = "pi5";
- nvidia,function = "rsvd2";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- pi6 {
- nvidia,pins = "pi6";
- nvidia,function = "rsvd1";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- pi7 {
- nvidia,pins = "pi7";
- nvidia,function = "rsvd1";
- nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
- nvidia,tristate = <TEGRA_PIN_ENABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- pj0 {
- nvidia,pins = "pj0";
- nvidia,function = "rsvd1";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- pj2 {
- nvidia,pins = "pj2";
- nvidia,function = "rsvd1";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- uart2_cts_n_pj5 {
- nvidia,pins = "uart2_cts_n_pj5";
- nvidia,function = "uartb";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- uart2_rts_n_pj6 {
- nvidia,pins = "uart2_rts_n_pj6";
- nvidia,function = "uartb";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- pj7 {
- nvidia,pins = "pj7";
- nvidia,function = "uartd";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- pk0 {
- nvidia,pins = "pk0";
- nvidia,function = "soc";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- pk1 {
- nvidia,pins = "pk1";
- nvidia,function = "rsvd4";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- pk2 {
- nvidia,pins = "pk2";
- nvidia,function = "rsvd1";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- pk3 {
- nvidia,pins = "pk3";
- nvidia,function = "gmi";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- pk4 {
- nvidia,pins = "pk4";
- nvidia,function = "rsvd2";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- spdif_out_pk5 {
- nvidia,pins = "spdif_out_pk5";
- nvidia,function = "rsvd2";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- spdif_in_pk6 {
- nvidia,pins = "spdif_in_pk6";
- nvidia,function = "rsvd2";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- pk7 {
- nvidia,pins = "pk7";
- nvidia,function = "uartd";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- dap1_fs_pn0 {
- nvidia,pins = "dap1_fs_pn0";
- nvidia,function = "i2s0";
- nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- dap1_din_pn1 {
- nvidia,pins = "dap1_din_pn1";
- nvidia,function = "i2s0";
- nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- dap1_dout_pn2 {
- nvidia,pins = "dap1_dout_pn2";
- nvidia,function = "sata";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- dap1_sclk_pn3 {
- nvidia,pins = "dap1_sclk_pn3";
- nvidia,function = "i2s0";
- nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- usb_vbus_en0_pn4 {
- nvidia,pins = "usb_vbus_en0_pn4";
- nvidia,function = "usb";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- nvidia,open-drain = <TEGRA_PIN_ENABLE>;
- };
- usb_vbus_en1_pn5 {
- nvidia,pins = "usb_vbus_en1_pn5";
- nvidia,function = "usb";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- nvidia,open-drain = <TEGRA_PIN_ENABLE>;
- };
- hdmi_int_pn7 {
- nvidia,pins = "hdmi_int_pn7";
- nvidia,function = "rsvd1";
- nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- nvidia,rcv-sel = <TEGRA_PIN_DISABLE>;
- };
- ulpi_data7_po0 {
- nvidia,pins = "ulpi_data7_po0";
- nvidia,function = "ulpi";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- ulpi_data0_po1 {
- nvidia,pins = "ulpi_data0_po1";
- nvidia,function = "ulpi";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- ulpi_data1_po2 {
- nvidia,pins = "ulpi_data1_po2";
- nvidia,function = "ulpi";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- ulpi_data2_po3 {
- nvidia,pins = "ulpi_data2_po3";
- nvidia,function = "ulpi";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- ulpi_data3_po4 {
- nvidia,pins = "ulpi_data3_po4";
- nvidia,function = "ulpi";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- ulpi_data4_po5 {
- nvidia,pins = "ulpi_data4_po5";
- nvidia,function = "ulpi";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- ulpi_data5_po6 {
- nvidia,pins = "ulpi_data5_po6";
- nvidia,function = "ulpi";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- ulpi_data6_po7 {
- nvidia,pins = "ulpi_data6_po7";
- nvidia,function = "ulpi";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- dap3_fs_pp0 {
- nvidia,pins = "dap3_fs_pp0";
- nvidia,function = "i2s2";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- dap3_din_pp1 {
- nvidia,pins = "dap3_din_pp1";
- nvidia,function = "i2s2";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- dap3_dout_pp2 {
- nvidia,pins = "dap3_dout_pp2";
- nvidia,function = "rsvd4";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- dap3_sclk_pp3 {
- nvidia,pins = "dap3_sclk_pp3";
- nvidia,function = "rsvd3";
- nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
- nvidia,tristate = <TEGRA_PIN_ENABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- dap4_fs_pp4 {
- nvidia,pins = "dap4_fs_pp4";
- nvidia,function = "i2s3";
- nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- dap4_din_pp5 {
- nvidia,pins = "dap4_din_pp5";
- nvidia,function = "i2s3";
- nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- dap4_dout_pp6 {
- nvidia,pins = "dap4_dout_pp6";
- nvidia,function = "i2s3";
- nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- dap4_sclk_pp7 {
- nvidia,pins = "dap4_sclk_pp7";
- nvidia,function = "i2s3";
- nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- kb_col0_pq0 {
- nvidia,pins = "kb_col0_pq0";
- nvidia,function = "rsvd2";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- kb_col1_pq1 {
- nvidia,pins = "kb_col1_pq1";
- nvidia,function = "rsvd2";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- kb_col2_pq2 {
- nvidia,pins = "kb_col2_pq2";
- nvidia,function = "rsvd2";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- kb_col3_pq3 {
- nvidia,pins = "kb_col3_pq3";
- nvidia,function = "kbc";
- nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
- nvidia,tristate = <TEGRA_PIN_ENABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- kb_col4_pq4 {
- nvidia,pins = "kb_col4_pq4";
- nvidia,function = "sdmmc3";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- kb_col5_pq5 {
- nvidia,pins = "kb_col5_pq5";
- nvidia,function = "rsvd2";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- kb_col6_pq6 {
- nvidia,pins = "kb_col6_pq6";
- nvidia,function = "rsvd2";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- kb_col7_pq7 {
- nvidia,pins = "kb_col7_pq7";
- nvidia,function = "rsvd2";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- kb_row0_pr0 {
- nvidia,pins = "kb_row0_pr0";
- nvidia,function = "rsvd2";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- kb_row1_pr1 {
- nvidia,pins = "kb_row1_pr1";
- nvidia,function = "rsvd2";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- kb_row2_pr2 {
- nvidia,pins = "kb_row2_pr2";
- nvidia,function = "rsvd2";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- kb_row3_pr3 {
- nvidia,pins = "kb_row3_pr3";
- nvidia,function = "sys";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- kb_row4_pr4 {
- nvidia,pins = "kb_row4_pr4";
- nvidia,function = "rsvd3";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- kb_row5_pr5 {
- nvidia,pins = "kb_row5_pr5";
- nvidia,function = "rsvd3";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- kb_row6_pr6 {
- nvidia,pins = "kb_row6_pr6";
- nvidia,function = "displaya_alt";
- nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- kb_row7_pr7 {
- nvidia,pins = "kb_row7_pr7";
- nvidia,function = "rsvd2";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- kb_row8_ps0 {
- nvidia,pins = "kb_row8_ps0";
- nvidia,function = "rsvd2";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- kb_row9_ps1 {
- nvidia,pins = "kb_row9_ps1";
- nvidia,function = "rsvd2";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- kb_row10_ps2 {
- nvidia,pins = "kb_row10_ps2";
- nvidia,function = "rsvd2";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- kb_row11_ps3 {
- nvidia,pins = "kb_row11_ps3";
- nvidia,function = "rsvd2";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- kb_row12_ps4 {
- nvidia,pins = "kb_row12_ps4";
- nvidia,function = "rsvd2";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- kb_row13_ps5 {
- nvidia,pins = "kb_row13_ps5";
- nvidia,function = "rsvd2";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- kb_row14_ps6 {
- nvidia,pins = "kb_row14_ps6";
- nvidia,function = "rsvd2";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- kb_row15_ps7 {
- nvidia,pins = "kb_row15_ps7";
- nvidia,function = "soc";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- kb_row16_pt0 {
- nvidia,pins = "kb_row16_pt0";
- nvidia,function = "rsvd2";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- kb_row17_pt1 {
- nvidia,pins = "kb_row17_pt1";
- nvidia,function = "rsvd2";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- gen2_i2c_scl_pt5 {
- nvidia,pins = "gen2_i2c_scl_pt5";
- nvidia,function = "i2c2";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- nvidia,open-drain = <TEGRA_PIN_ENABLE>;
- };
- gen2_i2c_sda_pt6 {
- nvidia,pins = "gen2_i2c_sda_pt6";
- nvidia,function = "i2c2";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- nvidia,open-drain = <TEGRA_PIN_ENABLE>;
- };
- sdmmc4_cmd_pt7 {
- nvidia,pins = "sdmmc4_cmd_pt7";
- nvidia,function = "sdmmc4";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- pu0 {
- nvidia,pins = "pu0";
- nvidia,function = "rsvd4";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- pu1 {
- nvidia,pins = "pu1";
- nvidia,function = "rsvd1";
- nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- pu2 {
- nvidia,pins = "pu2";
- nvidia,function = "rsvd1";
- nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- pu3 {
- nvidia,pins = "pu3";
- nvidia,function = "gmi";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- pu4 {
- nvidia,pins = "pu4";
- nvidia,function = "gmi";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- pu5 {
- nvidia,pins = "pu5";
- nvidia,function = "gmi";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- pu6 {
- nvidia,pins = "pu6";
- nvidia,function = "rsvd3";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- pv0 {
- nvidia,pins = "pv0";
- nvidia,function = "rsvd1";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- pv1 {
- nvidia,pins = "pv1";
- nvidia,function = "rsvd1";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- sdmmc3_cd_n_pv2 {
- nvidia,pins = "sdmmc3_cd_n_pv2";
- nvidia,function = "sdmmc3";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- sdmmc1_wp_n_pv3 {
- nvidia,pins = "sdmmc1_wp_n_pv3";
- nvidia,function = "sdmmc1";
- nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
- nvidia,tristate = <TEGRA_PIN_ENABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- ddc_scl_pv4 {
- nvidia,pins = "ddc_scl_pv4";
- nvidia,function = "i2c4";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- nvidia,rcv-sel = <TEGRA_PIN_DISABLE>;
- };
- ddc_sda_pv5 {
- nvidia,pins = "ddc_sda_pv5";
- nvidia,function = "i2c4";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- nvidia,rcv-sel = <TEGRA_PIN_DISABLE>;
- };
- gpio_w2_aud_pw2 {
- nvidia,pins = "gpio_w2_aud_pw2";
- nvidia,function = "rsvd2";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- gpio_w3_aud_pw3 {
- nvidia,pins = "gpio_w3_aud_pw3";
- nvidia,function = "spi6";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- dap_mclk1_pw4 {
- nvidia,pins = "dap_mclk1_pw4";
- nvidia,function = "extperiph1";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- clk2_out_pw5 {
- nvidia,pins = "clk2_out_pw5";
- nvidia,function = "extperiph2";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- uart3_txd_pw6 {
- nvidia,pins = "uart3_txd_pw6";
- nvidia,function = "uartc";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- uart3_rxd_pw7 {
- nvidia,pins = "uart3_rxd_pw7";
- nvidia,function = "uartc";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- dvfs_pwm_px0 {
- nvidia,pins = "dvfs_pwm_px0";
- nvidia,function = "cldvfs";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- gpio_x1_aud_px1 {
- nvidia,pins = "gpio_x1_aud_px1";
- nvidia,function = "rsvd2";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- dvfs_clk_px2 {
- nvidia,pins = "dvfs_clk_px2";
- nvidia,function = "cldvfs";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- gpio_x3_aud_px3 {
- nvidia,pins = "gpio_x3_aud_px3";
- nvidia,function = "rsvd4";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- gpio_x4_aud_px4 {
- nvidia,pins = "gpio_x4_aud_px4";
- nvidia,function = "gmi";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- gpio_x5_aud_px5 {
- nvidia,pins = "gpio_x5_aud_px5";
- nvidia,function = "rsvd4";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- gpio_x6_aud_px6 {
- nvidia,pins = "gpio_x6_aud_px6";
- nvidia,function = "gmi";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- gpio_x7_aud_px7 {
- nvidia,pins = "gpio_x7_aud_px7";
- nvidia,function = "rsvd1";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- ulpi_clk_py0 {
- nvidia,pins = "ulpi_clk_py0";
- nvidia,function = "spi1";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- ulpi_dir_py1 {
- nvidia,pins = "ulpi_dir_py1";
- nvidia,function = "spi1";
- nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- ulpi_nxt_py2 {
- nvidia,pins = "ulpi_nxt_py2";
- nvidia,function = "spi1";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- ulpi_stp_py3 {
- nvidia,pins = "ulpi_stp_py3";
- nvidia,function = "spi1";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- sdmmc1_dat3_py4 {
- nvidia,pins = "sdmmc1_dat3_py4";
- nvidia,function = "sdmmc1";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- sdmmc1_dat2_py5 {
- nvidia,pins = "sdmmc1_dat2_py5";
- nvidia,function = "sdmmc1";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- sdmmc1_dat1_py6 {
- nvidia,pins = "sdmmc1_dat1_py6";
- nvidia,function = "sdmmc1";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- sdmmc1_dat0_py7 {
- nvidia,pins = "sdmmc1_dat0_py7";
- nvidia,function = "sdmmc1";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- sdmmc1_clk_pz0 {
- nvidia,pins = "sdmmc1_clk_pz0";
- nvidia,function = "sdmmc1";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- sdmmc1_cmd_pz1 {
- nvidia,pins = "sdmmc1_cmd_pz1";
- nvidia,function = "sdmmc1";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- pwr_i2c_scl_pz6 {
- nvidia,pins = "pwr_i2c_scl_pz6";
- nvidia,function = "i2cpwr";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- nvidia,open-drain = <TEGRA_PIN_ENABLE>;
- };
- pwr_i2c_sda_pz7 {
- nvidia,pins = "pwr_i2c_sda_pz7";
- nvidia,function = "i2cpwr";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- nvidia,open-drain = <TEGRA_PIN_ENABLE>;
- };
- sdmmc4_dat0_paa0 {
- nvidia,pins = "sdmmc4_dat0_paa0";
- nvidia,function = "sdmmc4";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- sdmmc4_dat1_paa1 {
- nvidia,pins = "sdmmc4_dat1_paa1";
- nvidia,function = "sdmmc4";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- sdmmc4_dat2_paa2 {
- nvidia,pins = "sdmmc4_dat2_paa2";
- nvidia,function = "sdmmc4";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- sdmmc4_dat3_paa3 {
- nvidia,pins = "sdmmc4_dat3_paa3";
- nvidia,function = "sdmmc4";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- sdmmc4_dat4_paa4 {
- nvidia,pins = "sdmmc4_dat4_paa4";
- nvidia,function = "sdmmc4";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- sdmmc4_dat5_paa5 {
- nvidia,pins = "sdmmc4_dat5_paa5";
- nvidia,function = "sdmmc4";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- sdmmc4_dat6_paa6 {
- nvidia,pins = "sdmmc4_dat6_paa6";
- nvidia,function = "sdmmc4";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- sdmmc4_dat7_paa7 {
- nvidia,pins = "sdmmc4_dat7_paa7";
- nvidia,function = "sdmmc4";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- pbb0 {
- nvidia,pins = "pbb0";
- nvidia,function = "vimclk2_alt";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- cam_i2c_scl_pbb1 {
- nvidia,pins = "cam_i2c_scl_pbb1";
- nvidia,function = "i2c3";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- nvidia,open-drain = <TEGRA_PIN_ENABLE>;
- };
- cam_i2c_sda_pbb2 {
- nvidia,pins = "cam_i2c_sda_pbb2";
- nvidia,function = "i2c3";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- nvidia,open-drain = <TEGRA_PIN_ENABLE>;
- };
- pbb3 {
- nvidia,pins = "pbb3";
- nvidia,function = "vgp3";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- pbb4 {
- nvidia,pins = "pbb4";
- nvidia,function = "vgp4";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- pbb5 {
- nvidia,pins = "pbb5";
- nvidia,function = "rsvd3";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- pbb6 {
- nvidia,pins = "pbb6";
- nvidia,function = "rsvd2";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- pbb7 {
- nvidia,pins = "pbb7";
- nvidia,function = "rsvd2";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- cam_mclk_pcc0 {
- nvidia,pins = "cam_mclk_pcc0";
- nvidia,function = "vi_alt3";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- pcc1 {
- nvidia,pins = "pcc1";
- nvidia,function = "rsvd2";
- nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- pcc2 {
- nvidia,pins = "pcc2";
- nvidia,function = "rsvd2";
- nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- sdmmc4_clk_pcc4 {
- nvidia,pins = "sdmmc4_clk_pcc4";
- nvidia,function = "sdmmc4";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- clk2_req_pcc5 {
- nvidia,pins = "clk2_req_pcc5";
- nvidia,function = "rsvd2";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- clk3_out_pee0 {
- nvidia,pins = "clk3_out_pee0";
- nvidia,function = "extperiph3";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- clk3_req_pee1 {
- nvidia,pins = "clk3_req_pee1";
- nvidia,function = "rsvd2";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- dap_mclk1_req_pee2 {
- nvidia,pins = "dap_mclk1_req_pee2";
- nvidia,function = "sata";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- hdmi_cec_pee3 {
- nvidia,pins = "hdmi_cec_pee3";
- nvidia,function = "cec";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- nvidia,open-drain = <TEGRA_PIN_ENABLE>;
- };
- sdmmc3_clk_lb_out_pee4 {
- nvidia,pins = "sdmmc3_clk_lb_out_pee4";
- nvidia,function = "sdmmc3";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- sdmmc3_clk_lb_in_pee5 {
- nvidia,pins = "sdmmc3_clk_lb_in_pee5";
- nvidia,function = "sdmmc3";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- dp_hpd_pff0 {
- nvidia,pins = "dp_hpd_pff0";
- nvidia,function = "dp";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- usb_vbus_en2_pff1 {
- nvidia,pins = "usb_vbus_en2_pff1";
- nvidia,function = "rsvd2";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- nvidia,open-drain = <TEGRA_PIN_DISABLE>;
- };
- pff2 {
- nvidia,pins = "pff2";
- nvidia,function = "rsvd2";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- nvidia,open-drain = <TEGRA_PIN_DISABLE>;
- };
- core_pwr_req {
- nvidia,pins = "core_pwr_req";
- nvidia,function = "pwron";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- cpu_pwr_req {
- nvidia,pins = "cpu_pwr_req";
- nvidia,function = "rsvd2";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- pwr_int_n {
- nvidia,pins = "pwr_int_n";
- nvidia,function = "pmi";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- reset_out_n {
- nvidia,pins = "reset_out_n";
- nvidia,function = "reset_out_n";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- owr {
- nvidia,pins = "owr";
- nvidia,function = "rsvd2";
- nvidia,pull = <TEGRA_PIN_PULL_DOWN>;
- nvidia,tristate = <TEGRA_PIN_ENABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- nvidia,rcv-sel = <TEGRA_PIN_DISABLE>;
- };
- clk_32k_in {
- nvidia,pins = "clk_32k_in";
- nvidia,function = "rsvd2";
- nvidia,pull = <TEGRA_PIN_PULL_NONE>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_ENABLE>;
- };
- jtag_rtck {
- nvidia,pins = "jtag_rtck";
- nvidia,function = "rtck";
- nvidia,pull = <TEGRA_PIN_PULL_UP>;
- nvidia,tristate = <TEGRA_PIN_DISABLE>;
- nvidia,enable-input = <TEGRA_PIN_DISABLE>;
- };
- };
- };
-
- /* DB9 serial port */
- serial@0,70006300 {
- status = "okay";
- };
-
- /* Expansion GEN1_I2C_*, mini-PCIe I2C, on-board components */
- i2c@0,7000c000 {
- status = "okay";
- clock-frequency = <100000>;
-
- rt5639: audio-codec@1c {
- compatible = "realtek,rt5639";
- reg = <0x1c>;
- interrupt-parent = <&gpio>;
- interrupts = <TEGRA_GPIO(H, 4) GPIO_ACTIVE_HIGH>;
- realtek,ldo1-en-gpios =
- <&gpio TEGRA_GPIO(R, 2) GPIO_ACTIVE_HIGH>;
- };
-
- temperature-sensor@4c {
- compatible = "ti,tmp451";
- reg = <0x4c>;
- interrupt-parent = <&gpio>;
- interrupts = <TEGRA_GPIO(I, 6) IRQ_TYPE_LEVEL_LOW>;
- };
-
- eeprom@56 {
- compatible = "atmel,24c02";
- reg = <0x56>;
- pagesize = <8>;
- };
- };
-
- /* Expansion GEN2_I2C_* */
- i2c@0,7000c400 {
- status = "okay";
- clock-frequency = <100000>;
- };
-
- /* Expansion CAM_I2C_* */
- i2c@0,7000c500 {
- status = "okay";
- clock-frequency = <100000>;
- };
-
- /* HDMI DDC */
- hdmi_ddc: i2c@0,7000c700 {
- status = "okay";
- clock-frequency = <100000>;
- };
-
- /* Expansion PWR_I2C_*, on-board components */
- i2c@0,7000d000 {
- status = "okay";
- clock-frequency = <400000>;
-
- pmic: pmic@40 {
- compatible = "ams,as3722";
- reg = <0x40>;
- interrupts = <0 86 IRQ_TYPE_LEVEL_HIGH>;
-
- ams,system-power-controller;
-
- #interrupt-cells = <2>;
- interrupt-controller;
-
- gpio-controller;
- #gpio-cells = <2>;
-
- pinctrl-names = "default";
- pinctrl-0 = <&as3722_default>;
-
- as3722_default: pinmux {
- gpio0 {
- pins = "gpio0";
- function = "gpio";
- bias-pull-down;
- };
-
- gpio1_2_4_7 {
- pins = "gpio1", "gpio2", "gpio4", "gpio7";
- function = "gpio";
- bias-pull-up;
- };
-
- gpio3_5_6 {
- pins = "gpio3", "gpio5", "gpio6";
- bias-high-impedance;
- };
- };
-
- regulators {
- vsup-sd2-supply = <&vdd_5v0_sys>;
- vsup-sd3-supply = <&vdd_5v0_sys>;
- vsup-sd4-supply = <&vdd_5v0_sys>;
- vsup-sd5-supply = <&vdd_5v0_sys>;
- vin-ldo0-supply = <&vdd_1v35_lp0>;
- vin-ldo1-6-supply = <&vdd_3v3_run>;
- vin-ldo2-5-7-supply = <&vddio_1v8>;
- vin-ldo3-4-supply = <&vdd_3v3_sys>;
- vin-ldo9-10-supply = <&vdd_5v0_sys>;
- vin-ldo11-supply = <&vdd_3v3_run>;
-
- sd0 {
- regulator-name = "+VDD_CPU_AP";
- regulator-min-microvolt = <700000>;
- regulator-max-microvolt = <1400000>;
- regulator-min-microamp = <3500000>;
- regulator-max-microamp = <3500000>;
- regulator-always-on;
- regulator-boot-on;
- ams,external-control = <2>;
- };
-
- sd1 {
- regulator-name = "+VDD_CORE";
- regulator-min-microvolt = <700000>;
- regulator-max-microvolt = <1350000>;
- regulator-min-microamp = <2500000>;
- regulator-max-microamp = <2500000>;
- regulator-always-on;
- regulator-boot-on;
- ams,external-control = <1>;
- };
-
- vdd_1v35_lp0: sd2 {
- regulator-name = "+1.35V_LP0(sd2)";
- regulator-min-microvolt = <1350000>;
- regulator-max-microvolt = <1350000>;
- regulator-always-on;
- regulator-boot-on;
- };
-
- sd3 {
- regulator-name = "+1.35V_LP0(sd3)";
- regulator-min-microvolt = <1350000>;
- regulator-max-microvolt = <1350000>;
- regulator-always-on;
- regulator-boot-on;
- };
-
- vdd_1v05_run: sd4 {
- regulator-name = "+1.05V_RUN";
- regulator-min-microvolt = <1050000>;
- regulator-max-microvolt = <1050000>;
- };
-
- vddio_1v8: sd5 {
- regulator-name = "+1.8V_VDDIO";
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- regulator-boot-on;
- regulator-always-on;
- };
-
- sd6 {
- regulator-name = "+VDD_GPU_AP";
- regulator-min-microvolt = <650000>;
- regulator-max-microvolt = <1200000>;
- regulator-min-microamp = <3500000>;
- regulator-max-microamp = <3500000>;
- regulator-boot-on;
- regulator-always-on;
- };
-
- ldo0 {
- regulator-name = "+1.05V_RUN_AVDD";
- regulator-min-microvolt = <1050000>;
- regulator-max-microvolt = <1050000>;
- regulator-boot-on;
- regulator-always-on;
- ams,external-control = <1>;
- };
-
- ldo1 {
- regulator-name = "+1.8V_RUN_CAM";
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- };
-
- ldo2 {
- regulator-name = "+1.2V_GEN_AVDD";
- regulator-min-microvolt = <1200000>;
- regulator-max-microvolt = <1200000>;
- regulator-boot-on;
- regulator-always-on;
- };
-
- ldo3 {
- regulator-name = "+1.05V_LP0_VDD_RTC";
- regulator-min-microvolt = <1000000>;
- regulator-max-microvolt = <1000000>;
- regulator-boot-on;
- regulator-always-on;
- ams,enable-tracking;
- };
-
- ldo4 {
- regulator-name = "+2.8V_RUN_CAM";
- regulator-min-microvolt = <2800000>;
- regulator-max-microvolt = <2800000>;
- };
-
- ldo5 {
- regulator-name = "+1.2V_RUN_CAM_FRONT";
- regulator-min-microvolt = <1200000>;
- regulator-max-microvolt = <1200000>;
- };
-
- vddio_sdmmc3: ldo6 {
- regulator-name = "+VDDIO_SDMMC3";
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <3300000>;
- };
-
- ldo7 {
- regulator-name = "+1.05V_RUN_CAM_REAR";
- regulator-min-microvolt = <1050000>;
- regulator-max-microvolt = <1050000>;
- };
-
- ldo9 {
- regulator-name = "+3.3V_RUN_TOUCH";
- regulator-min-microvolt = <2800000>;
- regulator-max-microvolt = <2800000>;
- };
-
- ldo10 {
- regulator-name = "+2.8V_RUN_CAM_AF";
- regulator-min-microvolt = <2800000>;
- regulator-max-microvolt = <2800000>;
- };
+ chosen {
+ stdout-path = "/serial@0,70006300/";
- ldo11 {
- regulator-name = "+1.8V_RUN_VPP_FUSE";
- regulator-min-microvolt = <1800000>;
- regulator-max-microvolt = <1800000>;
- };
- };
+ environment@0 {
+ compatible = "barebox,environment";
+ device-path = &emmc, "partname:boot1";
};
};
- /* Expansion TS_SPI_* */
- spi@0,7000d400 {
- status = "okay";
- };
-
- /* Internal SPI */
- spi@0,7000da00 {
- status = "okay";
- spi-max-frequency = <25000000>;
- spi-flash@0 {
- compatible = "winbond,w25q32dw";
- reg = <0>;
- spi-max-frequency = <20000000>;
- };
- };
-
- pmc@0,7000e400 {
- nvidia,invert-interrupt;
- nvidia,suspend-mode = <1>;
- nvidia,cpu-pwr-good-time = <500>;
- nvidia,cpu-pwr-off-time = <300>;
- nvidia,core-pwr-good-time = <641 3845>;
- nvidia,core-pwr-off-time = <61036>;
- nvidia,core-power-req-active-high;
- nvidia,sys-clock-req-active-high;
- };
-
- /* SD card */
- sdhci@0,700b0400 {
- status = "okay";
- cd-gpios = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_LOW>;
- power-gpios = <&gpio TEGRA_GPIO(R, 0) GPIO_ACTIVE_HIGH>;
- wp-gpios = <&gpio TEGRA_GPIO(Q, 4) GPIO_ACTIVE_HIGH>;
- bus-width = <4>;
- vqmmc-supply = <&vddio_sdmmc3>;
- };
-
/* eMMC */
- sdhci@0,700b0600 {
- status = "okay";
- bus-width = <8>;
- non-removable;
- };
-
- ahub@0,70300000 {
- i2s@0,70301100 {
- status = "okay";
- };
- };
-
- /* mini-PCIe USB */
- usb@0,7d004000 {
- status = "okay";
- };
-
- usb-phy@0,7d004000 {
- status = "okay";
- };
-
- /* USB A connector */
- usb@0,7d008000 {
- status = "okay";
- };
-
- usb-phy@0,7d008000 {
- status = "okay";
- vbus-supply = <&vdd_usb3_vbus>;
- };
-
- clocks {
- compatible = "simple-bus";
- #address-cells = <1>;
- #size-cells = <0>;
-
- clk32k_in: clock@0 {
- compatible = "fixed-clock";
- reg = <0>;
- #clock-cells = <0>;
- clock-frequency = <32768>;
- };
- };
-
- gpio-keys {
- compatible = "gpio-keys";
-
- power {
- label = "Power";
- gpios = <&gpio TEGRA_GPIO(Q, 0) GPIO_ACTIVE_LOW>;
- linux,code = <KEY_POWER>;
- debounce-interval = <10>;
- gpio-key,wakeup;
- };
- };
-
- regulators {
- compatible = "simple-bus";
- #address-cells = <1>;
- #size-cells = <0>;
-
- vdd_mux: regulator@0 {
- compatible = "regulator-fixed";
- reg = <0>;
- regulator-name = "+VDD_MUX";
- regulator-min-microvolt = <12000000>;
- regulator-max-microvolt = <12000000>;
- regulator-always-on;
- regulator-boot-on;
- };
-
- vdd_5v0_sys: regulator@1 {
- compatible = "regulator-fixed";
- reg = <1>;
- regulator-name = "+5V_SYS";
- regulator-min-microvolt = <5000000>;
- regulator-max-microvolt = <5000000>;
- regulator-always-on;
- regulator-boot-on;
- vin-supply = <&vdd_mux>;
- };
-
- vdd_3v3_sys: regulator@2 {
- compatible = "regulator-fixed";
- reg = <2>;
- regulator-name = "+3.3V_SYS";
- regulator-min-microvolt = <3300000>;
- regulator-max-microvolt = <3300000>;
- regulator-always-on;
- regulator-boot-on;
- vin-supply = <&vdd_mux>;
- };
-
- vdd_3v3_run: regulator@3 {
- compatible = "regulator-fixed";
- reg = <3>;
- regulator-name = "+3.3V_RUN";
- regulator-min-microvolt = <3300000>;
- regulator-max-microvolt = <3300000>;
- regulator-always-on;
- regulator-boot-on;
- gpio = <&pmic 1 GPIO_ACTIVE_HIGH>;
- enable-active-high;
- vin-supply = <&vdd_3v3_sys>;
- };
-
- vdd_3v3_hdmi: regulator@4 {
- compatible = "regulator-fixed";
- reg = <4>;
- regulator-name = "+3.3V_AVDD_HDMI_AP_GATED";
- regulator-min-microvolt = <3300000>;
- regulator-max-microvolt = <3300000>;
- vin-supply = <&vdd_3v3_run>;
- };
-
- vdd_usb1_vbus: regulator@7 {
- compatible = "regulator-fixed";
- reg = <7>;
- regulator-name = "+USB0_VBUS_SW";
- regulator-min-microvolt = <5000000>;
- regulator-max-microvolt = <5000000>;
- gpio = <&gpio TEGRA_GPIO(N, 4) GPIO_ACTIVE_HIGH>;
- enable-active-high;
- gpio-open-drain;
- vin-supply = <&vdd_5v0_sys>;
- };
-
- vdd_usb3_vbus: regulator@8 {
- compatible = "regulator-fixed";
- reg = <8>;
- regulator-name = "+5V_USB_HS";
- regulator-min-microvolt = <5000000>;
- regulator-max-microvolt = <5000000>;
- gpio = <&gpio TEGRA_GPIO(N, 5) GPIO_ACTIVE_HIGH>;
- enable-active-high;
- gpio-open-drain;
- vin-supply = <&vdd_5v0_sys>;
- };
-
- vdd_3v3_lp0: regulator@10 {
- compatible = "regulator-fixed";
- reg = <10>;
- regulator-name = "+3.3V_LP0";
- regulator-min-microvolt = <3300000>;
- regulator-max-microvolt = <3300000>;
- regulator-always-on;
- regulator-boot-on;
- gpio = <&pmic 2 GPIO_ACTIVE_HIGH>;
- enable-active-high;
- vin-supply = <&vdd_3v3_sys>;
- };
-
- vdd_hdmi_pll: regulator@11 {
- compatible = "regulator-fixed";
- reg = <11>;
- regulator-name = "+1.05V_RUN_AVDD_HDMI_PLL";
- regulator-min-microvolt = <1050000>;
- regulator-max-microvolt = <1050000>;
- gpio = <&gpio TEGRA_GPIO(H, 7) GPIO_ACTIVE_LOW>;
- vin-supply = <&vdd_1v05_run>;
- };
-
- vdd_5v0_hdmi: regulator@12 {
- compatible = "regulator-fixed";
- reg = <12>;
- regulator-name = "+5V_HDMI_CON";
- regulator-min-microvolt = <5000000>;
- regulator-max-microvolt = <5000000>;
- gpio = <&gpio TEGRA_GPIO(K, 6) GPIO_ACTIVE_HIGH>;
- enable-active-high;
- vin-supply = <&vdd_5v0_sys>;
- };
- };
-
- sound {
- compatible = "nvidia,tegra-audio-rt5640-jetson-tk1",
- "nvidia,tegra-audio-rt5640";
- nvidia,model = "NVIDIA Tegra Jetson TK1";
-
- nvidia,audio-routing =
- "Headphones", "HPOR",
- "Headphones", "HPOL",
- "Mic Jack", "MICBIAS1",
- "IN2P", "Mic Jack";
-
- nvidia,i2s-controller = <&tegra_i2s1>;
- nvidia,audio-codec = <&rt5639>;
-
- nvidia,hp-det-gpios = <&gpio TEGRA_GPIO(R, 7) GPIO_ACTIVE_LOW>;
-
- clocks = <&tegra_car TEGRA124_CLK_PLL_A>,
- <&tegra_car TEGRA124_CLK_PLL_A_OUT0>,
- <&tegra_car TEGRA124_CLK_EXTERN1>;
- clock-names = "pll_a", "pll_a_out0", "mclk";
+ emmc: sdhci@0,700b0600 {
};
};
diff --git a/arch/arm/dts/tegra124.dtsi b/arch/arm/dts/tegra124.dtsi
index 7d0fafa862..c795811c57 100644
--- a/arch/arm/dts/tegra124.dtsi
+++ b/arch/arm/dts/tegra124.dtsi
@@ -1 +1,8 @@
-#include <arm/tegra124.dtsi>
+/ {
+ aliases {
+ serial0 = "/serial@0,70006000/";
+ serial1 = "/serial@0,70006040/";
+ serial2 = "/serial@0,70006200/";
+ serial3 = "/serial@0,70006300/";
+ };
+};
diff --git a/arch/arm/dts/tegra20-colibri-iris.dts b/arch/arm/dts/tegra20-colibri-iris.dts
index adfa917824..9c615816ca 100644
--- a/arch/arm/dts/tegra20-colibri-iris.dts
+++ b/arch/arm/dts/tegra20-colibri-iris.dts
@@ -6,6 +6,10 @@
model = "Toradex Colibri T20 on Iris";
compatible = "toradex,iris", "toradex,colibri_t20", "nvidia,tegra20";
+ chosen {
+ stdout-path = &uarta;
+ };
+
host1x@50000000 {
hdmi@54280000 {
status = "okay";
diff --git a/arch/arm/dts/tegra30-beaver.dts b/arch/arm/dts/tegra30-beaver.dts
index 35b4d7e43c..5879353fc6 100644
--- a/arch/arm/dts/tegra30-beaver.dts
+++ b/arch/arm/dts/tegra30-beaver.dts
@@ -1,6 +1,6 @@
/dts-v1/;
-#include "tegra30.dtsi"
+#include <arm/tegra30.dtsi>
/ {
model = "NVIDIA Tegra30 Beaver evaluation board";
@@ -11,6 +11,15 @@
rtc1 = "/rtc@7000e000";
};
+ chosen {
+ stdout-path = &uarta;
+
+ environment@0 {
+ compatible = "barebox,environment";
+ device-path = &emmc, "partname:boot1";
+ };
+ };
+
memory {
reg = <0x80000000 0x7ff00000>;
};
@@ -750,7 +759,7 @@
bus-width = <4>;
};
- sdhci@78000600 {
+ emmc: sdhci@78000600 {
status = "okay";
bus-width = <8>;
non-removable;
diff --git a/arch/arm/dts/tegra30.dtsi b/arch/arm/dts/tegra30.dtsi
deleted file mode 100644
index 19a84e933f..0000000000
--- a/arch/arm/dts/tegra30.dtsi
+++ /dev/null
@@ -1,892 +0,0 @@
-#include <dt-bindings/clock/tegra30-car.h>
-#include <dt-bindings/gpio/tegra-gpio.h>
-#include <dt-bindings/pinctrl/pinctrl-tegra.h>
-#include <dt-bindings/interrupt-controller/arm-gic.h>
-
-#include "skeleton.dtsi"
-
-/ {
- compatible = "nvidia,tegra30";
- interrupt-parent = <&intc>;
-
- aliases {
- serial0 = &uarta;
- serial1 = &uartb;
- serial2 = &uartc;
- serial3 = &uartd;
- serial4 = &uarte;
- };
-
- pcie-controller@00003000 {
- compatible = "nvidia,tegra30-pcie";
- device_type = "pci";
- reg = <0x00003000 0x00000800 /* PADS registers */
- 0x00003800 0x00000200 /* AFI registers */
- 0x10000000 0x10000000>; /* configuration space */
- reg-names = "pads", "afi", "cs";
- interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH /* controller interrupt */
- GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>; /* MSI interrupt */
- interrupt-names = "intr", "msi";
-
- bus-range = <0x00 0xff>;
- #address-cells = <3>;
- #size-cells = <2>;
-
- ranges = <0x82000000 0 0x00000000 0x00000000 0 0x00001000 /* port 0 configuration space */
- 0x82000000 0 0x00001000 0x00001000 0 0x00001000 /* port 1 configuration space */
- 0x82000000 0 0x00004000 0x00004000 0 0x00001000 /* port 2 configuration space */
- 0x81000000 0 0 0x02000000 0 0x00010000 /* downstream I/O */
- 0x82000000 0 0x20000000 0x20000000 0 0x08000000 /* non-prefetchable memory */
- 0xc2000000 0 0x28000000 0x28000000 0 0x18000000>; /* prefetchable memory */
-
- clocks = <&tegra_car TEGRA30_CLK_PCIE>,
- <&tegra_car TEGRA30_CLK_AFI>,
- <&tegra_car TEGRA30_CLK_PLL_E>,
- <&tegra_car TEGRA30_CLK_CML0>;
- clock-names = "pex", "afi", "pll_e", "cml";
- resets = <&tegra_car 70>,
- <&tegra_car 72>,
- <&tegra_car 74>;
- reset-names = "pex", "afi", "pcie_x";
- status = "disabled";
-
- pci@1,0 {
- device_type = "pci";
- assigned-addresses = <0x82000800 0 0x00000000 0 0x1000>;
- reg = <0x000800 0 0 0 0>;
- status = "disabled";
-
- #address-cells = <3>;
- #size-cells = <2>;
- ranges;
-
- nvidia,num-lanes = <2>;
- };
-
- pci@2,0 {
- device_type = "pci";
- assigned-addresses = <0x82001000 0 0x00001000 0 0x1000>;
- reg = <0x001000 0 0 0 0>;
- status = "disabled";
-
- #address-cells = <3>;
- #size-cells = <2>;
- ranges;
-
- nvidia,num-lanes = <2>;
- };
-
- pci@3,0 {
- device_type = "pci";
- assigned-addresses = <0x82001800 0 0x00004000 0 0x1000>;
- reg = <0x001800 0 0 0 0>;
- status = "disabled";
-
- #address-cells = <3>;
- #size-cells = <2>;
- ranges;
-
- nvidia,num-lanes = <2>;
- };
- };
-
- host1x@50000000 {
- compatible = "nvidia,tegra30-host1x", "simple-bus";
- reg = <0x50000000 0x00024000>;
- interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>, /* syncpt */
- <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>; /* general */
- clocks = <&tegra_car TEGRA30_CLK_HOST1X>;
- resets = <&tegra_car 28>;
- reset-names = "host1x";
-
- #address-cells = <1>;
- #size-cells = <1>;
-
- ranges = <0x54000000 0x54000000 0x04000000>;
-
- mpe@54040000 {
- compatible = "nvidia,tegra30-mpe";
- reg = <0x54040000 0x00040000>;
- interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&tegra_car TEGRA30_CLK_MPE>;
- resets = <&tegra_car 60>;
- reset-names = "mpe";
- };
-
- vi@54080000 {
- compatible = "nvidia,tegra30-vi";
- reg = <0x54080000 0x00040000>;
- interrupts = <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&tegra_car TEGRA30_CLK_VI>;
- resets = <&tegra_car 20>;
- reset-names = "vi";
- };
-
- epp@540c0000 {
- compatible = "nvidia,tegra30-epp";
- reg = <0x540c0000 0x00040000>;
- interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&tegra_car TEGRA30_CLK_EPP>;
- resets = <&tegra_car 19>;
- reset-names = "epp";
- };
-
- isp@54100000 {
- compatible = "nvidia,tegra30-isp";
- reg = <0x54100000 0x00040000>;
- interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&tegra_car TEGRA30_CLK_ISP>;
- resets = <&tegra_car 23>;
- reset-names = "isp";
- };
-
- gr2d@54140000 {
- compatible = "nvidia,tegra30-gr2d";
- reg = <0x54140000 0x00040000>;
- interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
- resets = <&tegra_car 21>;
- reset-names = "2d";
- clocks = <&tegra_car TEGRA30_CLK_GR2D>;
- };
-
- gr3d@54180000 {
- compatible = "nvidia,tegra30-gr3d";
- reg = <0x54180000 0x00040000>;
- clocks = <&tegra_car TEGRA30_CLK_GR3D
- &tegra_car TEGRA30_CLK_GR3D2>;
- clock-names = "3d", "3d2";
- resets = <&tegra_car 24>,
- <&tegra_car 98>;
- reset-names = "3d", "3d2";
- };
-
- dc@54200000 {
- compatible = "nvidia,tegra30-dc", "nvidia,tegra20-dc";
- reg = <0x54200000 0x00040000>;
- interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&tegra_car TEGRA30_CLK_DISP1>,
- <&tegra_car TEGRA30_CLK_PLL_P>;
- clock-names = "dc", "parent";
- resets = <&tegra_car 27>;
- reset-names = "dc";
-
- nvidia,head = <0>;
-
- rgb {
- status = "disabled";
- };
- };
-
- dc@54240000 {
- compatible = "nvidia,tegra30-dc";
- reg = <0x54240000 0x00040000>;
- interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&tegra_car TEGRA30_CLK_DISP2>,
- <&tegra_car TEGRA30_CLK_PLL_P>;
- clock-names = "dc", "parent";
- resets = <&tegra_car 26>;
- reset-names = "dc";
-
- nvidia,head = <1>;
-
- rgb {
- status = "disabled";
- };
- };
-
- hdmi@54280000 {
- compatible = "nvidia,tegra30-hdmi";
- reg = <0x54280000 0x00040000>;
- interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&tegra_car TEGRA30_CLK_HDMI>,
- <&tegra_car TEGRA30_CLK_PLL_D2_OUT0>;
- clock-names = "hdmi", "parent";
- resets = <&tegra_car 51>;
- reset-names = "hdmi";
- status = "disabled";
- };
-
- tvo@542c0000 {
- compatible = "nvidia,tegra30-tvo";
- reg = <0x542c0000 0x00040000>;
- interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&tegra_car TEGRA30_CLK_TVO>;
- status = "disabled";
- };
-
- dsi@54300000 {
- compatible = "nvidia,tegra30-dsi";
- reg = <0x54300000 0x00040000>;
- clocks = <&tegra_car TEGRA30_CLK_DSIA>;
- resets = <&tegra_car 48>;
- reset-names = "dsi";
- status = "disabled";
- };
- };
-
- timer@50004600 {
- compatible = "arm,cortex-a9-twd-timer";
- reg = <0x50040600 0x20>;
- interrupts = <GIC_PPI 13
- (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
- clocks = <&tegra_car TEGRA30_CLK_TWD>;
- };
-
- intc: interrupt-controller@50041000 {
- compatible = "arm,cortex-a9-gic";
- reg = <0x50041000 0x1000
- 0x50040100 0x0100>;
- interrupt-controller;
- #interrupt-cells = <3>;
- };
-
- cache-controller@50043000 {
- compatible = "arm,pl310-cache";
- reg = <0x50043000 0x1000>;
- arm,data-latency = <6 6 2>;
- arm,tag-latency = <5 5 2>;
- cache-unified;
- cache-level = <2>;
- };
-
- timer@60005000 {
- compatible = "nvidia,tegra30-timer", "nvidia,tegra20-timer";
- reg = <0x60005000 0x400>;
- interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&tegra_car TEGRA30_CLK_TIMER>;
- };
-
- tegra_car: clock@60006000 {
- compatible = "nvidia,tegra30-car";
- reg = <0x60006000 0x1000>;
- #clock-cells = <1>;
- #reset-cells = <1>;
- };
-
- apbdma: dma@6000a000 {
- compatible = "nvidia,tegra30-apbdma", "nvidia,tegra20-apbdma";
- reg = <0x6000a000 0x1400>;
- interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&tegra_car TEGRA30_CLK_APBDMA>;
- resets = <&tegra_car 34>;
- reset-names = "dma";
- #dma-cells = <1>;
- };
-
- ahb: ahb@6000c004 {
- compatible = "nvidia,tegra30-ahb";
- reg = <0x6000c004 0x14c>; /* AHB Arbitration + Gizmo Controller */
- };
-
- gpio: gpio@6000d000 {
- compatible = "nvidia,tegra30-gpio";
- reg = <0x6000d000 0x1000>;
- interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>;
- #gpio-cells = <2>;
- gpio-controller;
- #interrupt-cells = <2>;
- interrupt-controller;
- };
-
- pinmux: pinmux@70000868 {
- compatible = "nvidia,tegra30-pinmux";
- reg = <0x70000868 0xd4 /* Pad control registers */
- 0x70003000 0x3e4>; /* Mux registers */
- };
-
- /*
- * There are two serial driver i.e. 8250 based simple serial
- * driver and APB DMA based serial driver for higher baudrate
- * and performace. To enable the 8250 based driver, the compatible
- * is "nvidia,tegra30-uart", "nvidia,tegra20-uart" and to enable
- * the APB DMA based serial driver, the comptible is
- * "nvidia,tegra30-hsuart", "nvidia,tegra20-hsuart".
- */
- uarta: serial@70006000 {
- compatible = "nvidia,tegra30-uart", "nvidia,tegra20-uart";
- reg = <0x70006000 0x40>;
- reg-shift = <2>;
- interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&tegra_car TEGRA30_CLK_UARTA>;
- resets = <&tegra_car 6>;
- reset-names = "serial";
- dmas = <&apbdma 8>, <&apbdma 8>;
- dma-names = "rx", "tx";
- status = "disabled";
- };
-
- uartb: serial@70006040 {
- compatible = "nvidia,tegra30-uart", "nvidia,tegra20-uart";
- reg = <0x70006040 0x40>;
- reg-shift = <2>;
- interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&tegra_car TEGRA30_CLK_UARTB>;
- resets = <&tegra_car 7>;
- reset-names = "serial";
- dmas = <&apbdma 9>, <&apbdma 9>;
- dma-names = "rx", "tx";
- status = "disabled";
- };
-
- uartc: serial@70006200 {
- compatible = "nvidia,tegra30-uart", "nvidia,tegra20-uart";
- reg = <0x70006200 0x100>;
- reg-shift = <2>;
- interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&tegra_car TEGRA30_CLK_UARTC>;
- resets = <&tegra_car 55>;
- reset-names = "serial";
- dmas = <&apbdma 10>, <&apbdma 10>;
- dma-names = "rx", "tx";
- status = "disabled";
- };
-
- uartd: serial@70006300 {
- compatible = "nvidia,tegra30-uart", "nvidia,tegra20-uart";
- reg = <0x70006300 0x100>;
- reg-shift = <2>;
- interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&tegra_car TEGRA30_CLK_UARTD>;
- resets = <&tegra_car 65>;
- reset-names = "serial";
- dmas = <&apbdma 19>, <&apbdma 19>;
- dma-names = "rx", "tx";
- status = "disabled";
- };
-
- uarte: serial@70006400 {
- compatible = "nvidia,tegra30-uart", "nvidia,tegra20-uart";
- reg = <0x70006400 0x100>;
- reg-shift = <2>;
- interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&tegra_car TEGRA30_CLK_UARTE>;
- resets = <&tegra_car 66>;
- reset-names = "serial";
- dmas = <&apbdma 20>, <&apbdma 20>;
- dma-names = "rx", "tx";
- status = "disabled";
- };
-
- pwm: pwm@7000a000 {
- compatible = "nvidia,tegra30-pwm", "nvidia,tegra20-pwm";
- reg = <0x7000a000 0x100>;
- #pwm-cells = <2>;
- clocks = <&tegra_car TEGRA30_CLK_PWM>;
- resets = <&tegra_car 17>;
- reset-names = "pwm";
- status = "disabled";
- };
-
- rtc@7000e000 {
- compatible = "nvidia,tegra30-rtc", "nvidia,tegra20-rtc";
- reg = <0x7000e000 0x100>;
- interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&tegra_car TEGRA30_CLK_RTC>;
- };
-
- i2c@7000c000 {
- compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
- reg = <0x7000c000 0x100>;
- interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>;
- #address-cells = <1>;
- #size-cells = <0>;
- clocks = <&tegra_car TEGRA30_CLK_I2C1>,
- <&tegra_car TEGRA30_CLK_PLL_P_OUT3>;
- clock-names = "div-clk", "fast-clk";
- resets = <&tegra_car 12>;
- reset-names = "i2c";
- dmas = <&apbdma 21>, <&apbdma 21>;
- dma-names = "rx", "tx";
- status = "disabled";
- };
-
- i2c@7000c400 {
- compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
- reg = <0x7000c400 0x100>;
- interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
- #address-cells = <1>;
- #size-cells = <0>;
- clocks = <&tegra_car TEGRA30_CLK_I2C2>,
- <&tegra_car TEGRA30_CLK_PLL_P_OUT3>;
- clock-names = "div-clk", "fast-clk";
- resets = <&tegra_car 54>;
- reset-names = "i2c";
- dmas = <&apbdma 22>, <&apbdma 22>;
- dma-names = "rx", "tx";
- status = "disabled";
- };
-
- i2c@7000c500 {
- compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
- reg = <0x7000c500 0x100>;
- interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH>;
- #address-cells = <1>;
- #size-cells = <0>;
- clocks = <&tegra_car TEGRA30_CLK_I2C3>,
- <&tegra_car TEGRA30_CLK_PLL_P_OUT3>;
- clock-names = "div-clk", "fast-clk";
- resets = <&tegra_car 67>;
- reset-names = "i2c";
- dmas = <&apbdma 23>, <&apbdma 23>;
- dma-names = "rx", "tx";
- status = "disabled";
- };
-
- i2c@7000c700 {
- compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
- reg = <0x7000c700 0x100>;
- interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
- #address-cells = <1>;
- #size-cells = <0>;
- clocks = <&tegra_car TEGRA30_CLK_I2C4>,
- <&tegra_car TEGRA30_CLK_PLL_P_OUT3>;
- resets = <&tegra_car 103>;
- reset-names = "i2c";
- clock-names = "div-clk", "fast-clk";
- dmas = <&apbdma 26>, <&apbdma 26>;
- dma-names = "rx", "tx";
- status = "disabled";
- };
-
- i2c@7000d000 {
- compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
- reg = <0x7000d000 0x100>;
- interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
- #address-cells = <1>;
- #size-cells = <0>;
- clocks = <&tegra_car TEGRA30_CLK_I2C5>,
- <&tegra_car TEGRA30_CLK_PLL_P_OUT3>;
- clock-names = "div-clk", "fast-clk";
- resets = <&tegra_car 47>;
- reset-names = "i2c";
- dmas = <&apbdma 24>, <&apbdma 24>;
- dma-names = "rx", "tx";
- status = "disabled";
- };
-
- spi@7000d400 {
- compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink";
- reg = <0x7000d400 0x200>;
- interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>;
- #address-cells = <1>;
- #size-cells = <0>;
- clocks = <&tegra_car TEGRA30_CLK_SBC1>;
- resets = <&tegra_car 41>;
- reset-names = "spi";
- dmas = <&apbdma 15>, <&apbdma 15>;
- dma-names = "rx", "tx";
- status = "disabled";
- };
-
- spi@7000d600 {
- compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink";
- reg = <0x7000d600 0x200>;
- interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
- #address-cells = <1>;
- #size-cells = <0>;
- clocks = <&tegra_car TEGRA30_CLK_SBC2>;
- resets = <&tegra_car 44>;
- reset-names = "spi";
- dmas = <&apbdma 16>, <&apbdma 16>;
- dma-names = "rx", "tx";
- status = "disabled";
- };
-
- spi@7000d800 {
- compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink";
- reg = <0x7000d800 0x200>;
- interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
- #address-cells = <1>;
- #size-cells = <0>;
- clocks = <&tegra_car TEGRA30_CLK_SBC3>;
- resets = <&tegra_car 46>;
- reset-names = "spi";
- dmas = <&apbdma 17>, <&apbdma 17>;
- dma-names = "rx", "tx";
- status = "disabled";
- };
-
- spi@7000da00 {
- compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink";
- reg = <0x7000da00 0x200>;
- interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
- #address-cells = <1>;
- #size-cells = <0>;
- clocks = <&tegra_car TEGRA30_CLK_SBC4>;
- resets = <&tegra_car 68>;
- reset-names = "spi";
- dmas = <&apbdma 18>, <&apbdma 18>;
- dma-names = "rx", "tx";
- status = "disabled";
- };
-
- spi@7000dc00 {
- compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink";
- reg = <0x7000dc00 0x200>;
- interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
- #address-cells = <1>;
- #size-cells = <0>;
- clocks = <&tegra_car TEGRA30_CLK_SBC5>;
- resets = <&tegra_car 104>;
- reset-names = "spi";
- dmas = <&apbdma 27>, <&apbdma 27>;
- dma-names = "rx", "tx";
- status = "disabled";
- };
-
- spi@7000de00 {
- compatible = "nvidia,tegra30-slink", "nvidia,tegra20-slink";
- reg = <0x7000de00 0x200>;
- interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
- #address-cells = <1>;
- #size-cells = <0>;
- clocks = <&tegra_car TEGRA30_CLK_SBC6>;
- resets = <&tegra_car 106>;
- reset-names = "spi";
- dmas = <&apbdma 28>, <&apbdma 28>;
- dma-names = "rx", "tx";
- status = "disabled";
- };
-
- kbc@7000e200 {
- compatible = "nvidia,tegra30-kbc", "nvidia,tegra20-kbc";
- reg = <0x7000e200 0x100>;
- interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&tegra_car TEGRA30_CLK_KBC>;
- resets = <&tegra_car 36>;
- reset-names = "kbc";
- status = "disabled";
- };
-
- pmc@7000e400 {
- compatible = "nvidia,tegra30-pmc";
- reg = <0x7000e400 0x400>;
- clocks = <&tegra_car TEGRA30_CLK_PCLK>, <&clk32k_in>;
- clock-names = "pclk", "clk32k_in";
- };
-
- memory-controller@7000f000 {
- compatible = "nvidia,tegra30-mc";
- reg = <0x7000f000 0x010
- 0x7000f03c 0x1b4
- 0x7000f200 0x028
- 0x7000f284 0x17c>;
- interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
- };
-
- iommu@7000f010 {
- compatible = "nvidia,tegra30-smmu";
- reg = <0x7000f010 0x02c
- 0x7000f1f0 0x010
- 0x7000f228 0x05c>;
- nvidia,#asids = <4>; /* # of ASIDs */
- dma-window = <0 0x40000000>; /* IOVA start & length */
- nvidia,ahb = <&ahb>;
- };
-
- ahub@70080000 {
- compatible = "nvidia,tegra30-ahub";
- reg = <0x70080000 0x200
- 0x70080200 0x100>;
- interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&tegra_car TEGRA30_CLK_D_AUDIO>,
- <&tegra_car TEGRA30_CLK_APBIF>;
- clock-names = "d_audio", "apbif";
- resets = <&tegra_car 106>, /* d_audio */
- <&tegra_car 107>, /* apbif */
- <&tegra_car 30>, /* i2s0 */
- <&tegra_car 11>, /* i2s1 */
- <&tegra_car 18>, /* i2s2 */
- <&tegra_car 101>, /* i2s3 */
- <&tegra_car 102>, /* i2s4 */
- <&tegra_car 108>, /* dam0 */
- <&tegra_car 109>, /* dam1 */
- <&tegra_car 110>, /* dam2 */
- <&tegra_car 10>; /* spdif */
- reset-names = "d_audio", "apbif", "i2s0", "i2s1", "i2s2",
- "i2s3", "i2s4", "dam0", "dam1", "dam2",
- "spdif";
- dmas = <&apbdma 1>, <&apbdma 1>,
- <&apbdma 2>, <&apbdma 2>,
- <&apbdma 3>, <&apbdma 3>,
- <&apbdma 4>, <&apbdma 4>;
- dma-names = "rx0", "tx0", "rx1", "tx1", "rx2", "tx2",
- "rx3", "tx3";
- ranges;
- #address-cells = <1>;
- #size-cells = <1>;
-
- tegra_i2s0: i2s@70080300 {
- compatible = "nvidia,tegra30-i2s";
- reg = <0x70080300 0x100>;
- nvidia,ahub-cif-ids = <4 4>;
- clocks = <&tegra_car TEGRA30_CLK_I2S0>;
- resets = <&tegra_car 30>;
- reset-names = "i2s";
- status = "disabled";
- };
-
- tegra_i2s1: i2s@70080400 {
- compatible = "nvidia,tegra30-i2s";
- reg = <0x70080400 0x100>;
- nvidia,ahub-cif-ids = <5 5>;
- clocks = <&tegra_car TEGRA30_CLK_I2S1>;
- resets = <&tegra_car 11>;
- reset-names = "i2s";
- status = "disabled";
- };
-
- tegra_i2s2: i2s@70080500 {
- compatible = "nvidia,tegra30-i2s";
- reg = <0x70080500 0x100>;
- nvidia,ahub-cif-ids = <6 6>;
- clocks = <&tegra_car TEGRA30_CLK_I2S2>;
- resets = <&tegra_car 18>;
- reset-names = "i2s";
- status = "disabled";
- };
-
- tegra_i2s3: i2s@70080600 {
- compatible = "nvidia,tegra30-i2s";
- reg = <0x70080600 0x100>;
- nvidia,ahub-cif-ids = <7 7>;
- clocks = <&tegra_car TEGRA30_CLK_I2S3>;
- resets = <&tegra_car 101>;
- reset-names = "i2s";
- status = "disabled";
- };
-
- tegra_i2s4: i2s@70080700 {
- compatible = "nvidia,tegra30-i2s";
- reg = <0x70080700 0x100>;
- nvidia,ahub-cif-ids = <8 8>;
- clocks = <&tegra_car TEGRA30_CLK_I2S4>;
- resets = <&tegra_car 102>;
- reset-names = "i2s";
- status = "disabled";
- };
- };
-
- sdhci@78000000 {
- compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci";
- reg = <0x78000000 0x200>;
- interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&tegra_car TEGRA30_CLK_SDMMC1>;
- resets = <&tegra_car 14>;
- reset-names = "sdhci";
- status = "disabled";
- };
-
- sdhci@78000200 {
- compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci";
- reg = <0x78000200 0x200>;
- interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&tegra_car TEGRA30_CLK_SDMMC2>;
- resets = <&tegra_car 9>;
- reset-names = "sdhci";
- status = "disabled";
- };
-
- sdhci@78000400 {
- compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci";
- reg = <0x78000400 0x200>;
- interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&tegra_car TEGRA30_CLK_SDMMC3>;
- resets = <&tegra_car 69>;
- reset-names = "sdhci";
- status = "disabled";
- };
-
- sdhci@78000600 {
- compatible = "nvidia,tegra30-sdhci", "nvidia,tegra20-sdhci";
- reg = <0x78000600 0x200>;
- interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&tegra_car TEGRA30_CLK_SDMMC4>;
- resets = <&tegra_car 15>;
- reset-names = "sdhci";
- status = "disabled";
- };
-
- usb@7d000000 {
- compatible = "nvidia,tegra30-ehci", "usb-ehci";
- reg = <0x7d000000 0x4000>;
- interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
- phy_type = "utmi";
- clocks = <&tegra_car TEGRA30_CLK_USBD>;
- resets = <&tegra_car 22>;
- reset-names = "usb";
- nvidia,needs-double-reset;
- nvidia,phy = <&phy1>;
- status = "disabled";
- };
-
- phy1: usb-phy@7d000000 {
- compatible = "nvidia,tegra30-usb-phy";
- reg = <0x7d000000 0x4000 0x7d000000 0x4000>;
- phy_type = "utmi";
- clocks = <&tegra_car TEGRA30_CLK_USBD>,
- <&tegra_car TEGRA30_CLK_PLL_U>,
- <&tegra_car TEGRA30_CLK_USBD>;
- clock-names = "reg", "pll_u", "utmi-pads";
- nvidia,hssync-start-delay = <9>;
- nvidia,idle-wait-delay = <17>;
- nvidia,elastic-limit = <16>;
- nvidia,term-range-adj = <6>;
- nvidia,xcvr-setup = <51>;
- nvidia.xcvr-setup-use-fuses;
- nvidia,xcvr-lsfslew = <1>;
- nvidia,xcvr-lsrslew = <1>;
- nvidia,xcvr-hsslew = <32>;
- nvidia,hssquelch-level = <2>;
- nvidia,hsdiscon-level = <5>;
- status = "disabled";
- };
-
- usb@7d004000 {
- compatible = "nvidia,tegra30-ehci", "usb-ehci";
- reg = <0x7d004000 0x4000>;
- interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
- phy_type = "utmi";
- clocks = <&tegra_car TEGRA30_CLK_USB2>;
- resets = <&tegra_car 58>;
- reset-names = "usb";
- nvidia,phy = <&phy2>;
- status = "disabled";
- };
-
- phy2: usb-phy@7d004000 {
- compatible = "nvidia,tegra30-usb-phy";
- reg = <0x7d004000 0x4000 0x7d000000 0x4000>;
- phy_type = "utmi";
- clocks = <&tegra_car TEGRA30_CLK_USB2>,
- <&tegra_car TEGRA30_CLK_PLL_U>,
- <&tegra_car TEGRA30_CLK_USBD>;
- clock-names = "reg", "pll_u", "utmi-pads";
- nvidia,hssync-start-delay = <9>;
- nvidia,idle-wait-delay = <17>;
- nvidia,elastic-limit = <16>;
- nvidia,term-range-adj = <6>;
- nvidia,xcvr-setup = <51>;
- nvidia.xcvr-setup-use-fuses;
- nvidia,xcvr-lsfslew = <2>;
- nvidia,xcvr-lsrslew = <2>;
- nvidia,xcvr-hsslew = <32>;
- nvidia,hssquelch-level = <2>;
- nvidia,hsdiscon-level = <5>;
- status = "disabled";
- };
-
- usb@7d008000 {
- compatible = "nvidia,tegra30-ehci", "usb-ehci";
- reg = <0x7d008000 0x4000>;
- interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
- phy_type = "utmi";
- clocks = <&tegra_car TEGRA30_CLK_USB3>;
- resets = <&tegra_car 59>;
- reset-names = "usb";
- nvidia,phy = <&phy3>;
- status = "disabled";
- };
-
- phy3: usb-phy@7d008000 {
- compatible = "nvidia,tegra30-usb-phy";
- reg = <0x7d008000 0x4000 0x7d000000 0x4000>;
- phy_type = "utmi";
- clocks = <&tegra_car TEGRA30_CLK_USB3>,
- <&tegra_car TEGRA30_CLK_PLL_U>,
- <&tegra_car TEGRA30_CLK_USBD>;
- clock-names = "reg", "pll_u", "utmi-pads";
- nvidia,hssync-start-delay = <0>;
- nvidia,idle-wait-delay = <17>;
- nvidia,elastic-limit = <16>;
- nvidia,term-range-adj = <6>;
- nvidia,xcvr-setup = <51>;
- nvidia.xcvr-setup-use-fuses;
- nvidia,xcvr-lsfslew = <2>;
- nvidia,xcvr-lsrslew = <2>;
- nvidia,xcvr-hsslew = <32>;
- nvidia,hssquelch-level = <2>;
- nvidia,hsdiscon-level = <5>;
- status = "disabled";
- };
-
- cpus {
- #address-cells = <1>;
- #size-cells = <0>;
-
- cpu@0 {
- device_type = "cpu";
- compatible = "arm,cortex-a9";
- reg = <0>;
- };
-
- cpu@1 {
- device_type = "cpu";
- compatible = "arm,cortex-a9";
- reg = <1>;
- };
-
- cpu@2 {
- device_type = "cpu";
- compatible = "arm,cortex-a9";
- reg = <2>;
- };
-
- cpu@3 {
- device_type = "cpu";
- compatible = "arm,cortex-a9";
- reg = <3>;
- };
- };
-
- pmu {
- compatible = "arm,cortex-a9-pmu";
- interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>,
- <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
- };
-};
diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig
index 2c69406dfc..160732fbef 100644
--- a/arch/arm/mach-tegra/Kconfig
+++ b/arch/arm/mach-tegra/Kconfig
@@ -7,39 +7,6 @@ config ARCH_TEXT_BASE
config BOARDINFO
default ""
-choice
- prompt "Tegra debug UART"
- help
- This is the first serial console that gets activated by barebox.
- Normally each board vendor should program a valid debug UART into
- the ODMdata section of the boot configuration table, so it's a
- reasonably good bet to use that.
- If you know your ODMdata is broken, or you don't wish to activate
- any serial console at all you can override the default here.
-
-config TEGRA_UART_ODMDATA
- bool "ODMdata defined UART"
-
-config TEGRA_UART_A
- bool "UART A"
-
-config TEGRA_UART_B
- bool "UART B"
-
-config TEGRA_UART_C
- bool "UART C"
-
-config TEGRA_UART_D
- bool "UART D"
-
-config TEGRA_UART_E
- bool "UART E"
-
-config TEGRA_UART_NONE
- bool "None"
-
-endchoice
-
# ---------------------------------------------------------
config ARCH_TEGRA_2x_SOC
@@ -70,6 +37,8 @@ config MACH_NVIDIA_BEAVER
config MACH_NVIDIA_JETSON
bool "NVIDIA Jetson TK1"
select ARCH_TEGRA_124_SOC
+ select I2C
+ select I2C_TEGRA
endmenu
diff --git a/arch/arm/mach-tegra/include/mach/lowlevel.h b/arch/arm/mach-tegra/include/mach/lowlevel.h
index c65be0b7ba..3e7e41b990 100644
--- a/arch/arm/mach-tegra/include/mach/lowlevel.h
+++ b/arch/arm/mach-tegra/include/mach/lowlevel.h
@@ -176,37 +176,6 @@ uint32_t tegra30_get_ramsize(void)
}
}
-static long uart_id_to_base[] = {
- TEGRA_UARTA_BASE,
- TEGRA_UARTB_BASE,
- TEGRA_UARTC_BASE,
- TEGRA_UARTD_BASE,
- TEGRA_UARTE_BASE,
-};
-
-static __always_inline
-long tegra20_get_debuguart_base(void)
-{
- u32 odmdata;
- int id;
-
- odmdata = tegra_get_odmdata();
-
- /*
- * Get type, we accept both "2" and "3", as they both demark a UART,
- * depending on the board type.
- */
- if (!(((odmdata & T20_ODMDATA_UARTTYPE_MASK) >>
- T20_ODMDATA_UARTTYPE_SHIFT) & 0x2))
- return 0;
-
- id = (odmdata & T20_ODMDATA_UARTID_MASK) >> T20_ODMDATA_UARTID_SHIFT;
- if (id > ARRAY_SIZE(uart_id_to_base))
- return 0;
-
- return uart_id_to_base[id];
-}
-
#define CRC_OSC_CTRL 0x050
#define CRC_OSC_CTRL_OSC_FREQ_SHIFT 30
#define CRC_OSC_CTRL_OSC_FREQ_MASK (0x3 << CRC_OSC_CTRL_OSC_FREQ_SHIFT)
@@ -231,20 +200,6 @@ int tegra_get_osc_clock(void)
}
}
-static __always_inline
-int tegra_get_pllp_rate(void)
-{
- switch (tegra_get_chiptype()) {
- case TEGRA20:
- return 216000000;
- case TEGRA30:
- case TEGRA124:
- return 408000000;
- default:
- return 0;
- }
-}
-
#define TIMER_CNTR_1US 0x00
#define TIMER_USEC_CFG 0x04
diff --git a/arch/arm/mach-tegra/include/mach/tegra-powergate.h b/arch/arm/mach-tegra/include/mach/tegra-powergate.h
new file mode 100644
index 0000000000..e32250a7fa
--- /dev/null
+++ b/arch/arm/mach-tegra/include/mach/tegra-powergate.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2010 Google, Inc
+ *
+ * Author:
+ * Colin Cross <ccross@google.com>
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that 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.
+ *
+ */
+
+#ifndef _MACH_TEGRA_POWERGATE_H_
+#define _MACH_TEGRA_POWERGATE_H_
+
+struct clk;
+struct reset_control;
+
+#define TEGRA_POWERGATE_CPU 0
+#define TEGRA_POWERGATE_3D 1
+#define TEGRA_POWERGATE_VENC 2
+#define TEGRA_POWERGATE_PCIE 3
+#define TEGRA_POWERGATE_VDEC 4
+#define TEGRA_POWERGATE_L2 5
+#define TEGRA_POWERGATE_MPE 6
+#define TEGRA_POWERGATE_HEG 7
+#define TEGRA_POWERGATE_SATA 8
+#define TEGRA_POWERGATE_CPU1 9
+#define TEGRA_POWERGATE_CPU2 10
+#define TEGRA_POWERGATE_CPU3 11
+#define TEGRA_POWERGATE_CELP 12
+#define TEGRA_POWERGATE_3D1 13
+#define TEGRA_POWERGATE_CPU0 14
+#define TEGRA_POWERGATE_C0NC 15
+#define TEGRA_POWERGATE_C1NC 16
+#define TEGRA_POWERGATE_SOR 17
+#define TEGRA_POWERGATE_DIS 18
+#define TEGRA_POWERGATE_DISB 19
+#define TEGRA_POWERGATE_XUSBA 20
+#define TEGRA_POWERGATE_XUSBB 21
+#define TEGRA_POWERGATE_XUSBC 22
+#define TEGRA_POWERGATE_VIC 23
+#define TEGRA_POWERGATE_IRAM 24
+
+#define TEGRA_POWERGATE_3D0 TEGRA_POWERGATE_3D
+
+#define TEGRA_IO_RAIL_CSIA 0
+#define TEGRA_IO_RAIL_CSIB 1
+#define TEGRA_IO_RAIL_DSI 2
+#define TEGRA_IO_RAIL_MIPI_BIAS 3
+#define TEGRA_IO_RAIL_PEX_BIAS 4
+#define TEGRA_IO_RAIL_PEX_CLK1 5
+#define TEGRA_IO_RAIL_PEX_CLK2 6
+#define TEGRA_IO_RAIL_USB0 9
+#define TEGRA_IO_RAIL_USB1 10
+#define TEGRA_IO_RAIL_USB2 11
+#define TEGRA_IO_RAIL_USB_BIAS 12
+#define TEGRA_IO_RAIL_NAND 13
+#define TEGRA_IO_RAIL_UART 14
+#define TEGRA_IO_RAIL_BB 15
+#define TEGRA_IO_RAIL_AUDIO 17
+#define TEGRA_IO_RAIL_HSIC 19
+#define TEGRA_IO_RAIL_COMP 22
+#define TEGRA_IO_RAIL_HDMI 28
+#define TEGRA_IO_RAIL_PEX_CNTRL 32
+#define TEGRA_IO_RAIL_SDMMC1 33
+#define TEGRA_IO_RAIL_SDMMC3 34
+#define TEGRA_IO_RAIL_SDMMC4 35
+#define TEGRA_IO_RAIL_CAM 36
+#define TEGRA_IO_RAIL_RES 37
+#define TEGRA_IO_RAIL_HV 38
+#define TEGRA_IO_RAIL_DSIB 39
+#define TEGRA_IO_RAIL_DSIC 40
+#define TEGRA_IO_RAIL_DSID 41
+#define TEGRA_IO_RAIL_CSIE 44
+#define TEGRA_IO_RAIL_LVDS 57
+#define TEGRA_IO_RAIL_SYS_DDC 58
+
+int tegra_powergate_is_powered(int id);
+int tegra_powergate_power_on(int id);
+int tegra_powergate_power_off(int id);
+int tegra_powergate_remove_clamping(int id);
+
+/* Must be called with clk disabled, and returns with clk enabled */
+int tegra_powergate_sequence_power_up(int id, struct clk *clk,
+ struct reset_control *rst);
+
+#endif /* _MACH_TEGRA_POWERGATE_H_ */
diff --git a/arch/arm/mach-tegra/include/mach/tegra20-car.h b/arch/arm/mach-tegra/include/mach/tegra20-car.h
index 161e3d82a1..5a35f21c1f 100644
--- a/arch/arm/mach-tegra/include/mach/tegra20-car.h
+++ b/arch/arm/mach-tegra/include/mach/tegra20-car.h
@@ -49,6 +49,8 @@
#define CRC_CLK_OUT_ENB_H 0x014
#define CRC_CLK_OUT_ENB_H_DVC (1 << 15)
+#define CRC_CLK_OUT_ENB_U 0x018
+
#define CRC_CCLK_BURST_POLICY 0x020
#define CRC_CCLK_BURST_POLICY_SYS_STATE_SHIFT 28
#define CRC_CCLK_BURST_POLICY_SYS_STATE_FIQ 8
diff --git a/arch/arm/mach-tegra/include/mach/tegra20-pmc.h b/arch/arm/mach-tegra/include/mach/tegra20-pmc.h
index 30ac06508c..c379544755 100644
--- a/arch/arm/mach-tegra/include/mach/tegra20-pmc.h
+++ b/arch/arm/mach-tegra/include/mach/tegra20-pmc.h
@@ -71,3 +71,12 @@
#define PMC_PARTID_C0NC 15
#define PMC_SCRATCH(i) (0x050 + 0x4*i)
+
+#define PMC_RST_STATUS 0x1b4
+#define PMC_RST_STATUS_RST_SRC_SHIFT 0
+#define PMC_RST_STATUS_RST_SRC_MASK (0x7 << PMC_RST_STATUS_RST_SRC_SHIFT)
+#define PMC_RST_STATUS_RST_SRC_POR 0
+#define PMC_RST_STATUS_RST_SRC_WATCHDOG 1
+#define PMC_RST_STATUS_RST_SRC_SENSOR 2
+#define PMC_RST_STATUS_RST_SRC_SW_MAIN 3
+#define PMC_RST_STATUS_RST_SRC_LP0 4
diff --git a/arch/arm/mach-tegra/include/mach/tegra30-car.h b/arch/arm/mach-tegra/include/mach/tegra30-car.h
index c8f6c9fd54..7fb2238dc9 100644
--- a/arch/arm/mach-tegra/include/mach/tegra30-car.h
+++ b/arch/arm/mach-tegra/include/mach/tegra30-car.h
@@ -33,3 +33,5 @@
#define CRC_RST_DEV_V_CLR 0x434
#define CRC_CLK_OUT_ENB_V_SET 0x440
+
+#define CRC_PLLE_AUX 0x48c
diff --git a/arch/arm/mach-tegra/tegra20-pmc.c b/arch/arm/mach-tegra/tegra20-pmc.c
index d86809432e..eaa5ac73ff 100644
--- a/arch/arm/mach-tegra/tegra20-pmc.c
+++ b/arch/arm/mach-tegra/tegra20-pmc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Lucas Stach <l.stach@pengutronix.de>
+ * Copyright (C) 2013-2014 Lucas Stach <l.stach@pengutronix.de>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -19,15 +19,21 @@
* @brief Device driver for the Tegra 20 power management controller.
*/
-#include <common.h>
#include <command.h>
+#include <common.h>
#include <init.h>
#include <io.h>
#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/reset.h>
+#include <mach/lowlevel.h>
+#include <mach/tegra-powergate.h>
+#include <reset_source.h>
#include <mach/tegra20-pmc.h>
static void __iomem *pmc_base;
+static int tegra_num_powerdomains;
/* main SoC reset trigger */
void __noreturn reset_cpu(ulong addr)
@@ -38,6 +44,162 @@ void __noreturn reset_cpu(ulong addr)
}
EXPORT_SYMBOL(reset_cpu);
+static int tegra_powergate_set(int id, bool new_state)
+{
+ bool status;
+
+ status = readl(pmc_base + PMC_PWRGATE_STATUS) & (1 << id);
+
+ if (status == new_state) {
+ return 0;
+ }
+
+ writel(PMC_PWRGATE_TOGGLE_START | id, pmc_base + PMC_PWRGATE_TOGGLE);
+ /* I don't know exactly why this is needed, seems to flush the write */
+ readl(pmc_base + PMC_PWRGATE_TOGGLE);
+
+ return 0;
+}
+
+int tegra_powergate_power_on(int id)
+{
+ if (id < 0 || id >= tegra_num_powerdomains)
+ return -EINVAL;
+
+ return tegra_powergate_set(id, true);
+}
+
+int tegra_powergate_power_off(int id)
+{
+ if (id < 0 || id >= tegra_num_powerdomains)
+ return -EINVAL;
+
+ return tegra_powergate_set(id, false);
+}
+EXPORT_SYMBOL(tegra_powergate_power_off);
+
+int tegra_powergate_is_powered(int id)
+{
+ u32 status;
+
+ if (id < 0 || id >= tegra_num_powerdomains)
+ return -EINVAL;
+
+ status = readl(pmc_base + PMC_PWRGATE_STATUS) & (1 << id);
+ return !!status;
+}
+
+int tegra_powergate_remove_clamping(int id)
+{
+ u32 mask;
+
+ if (id < 0 || id >= tegra_num_powerdomains)
+ return -EINVAL;
+
+ /*
+ * Tegra 2 has a bug where PCIE and VDE clamping masks are
+ * swapped relatively to the partition ids
+ */
+ if (id == TEGRA_POWERGATE_VDEC)
+ mask = (1 << TEGRA_POWERGATE_PCIE);
+ else if (id == TEGRA_POWERGATE_PCIE)
+ mask = (1 << TEGRA_POWERGATE_VDEC);
+ else
+ mask = (1 << id);
+
+ writel(mask, pmc_base + PMC_REMOVE_CLAMPING_CMD);
+
+ return 0;
+}
+EXPORT_SYMBOL(tegra_powergate_remove_clamping);
+
+/* Must be called with clk disabled, and returns with clk enabled */
+int tegra_powergate_sequence_power_up(int id, struct clk *clk,
+ struct reset_control *rst)
+{
+ int ret;
+
+ reset_control_assert(rst);
+
+ ret = tegra_powergate_power_on(id);
+ if (ret)
+ goto err_power;
+
+ ret = clk_enable(clk);
+ if (ret)
+ goto err_clk;
+
+ udelay(10);
+
+ ret = tegra_powergate_remove_clamping(id);
+ if (ret)
+ goto err_clamp;
+
+ udelay(10);
+ reset_control_deassert(rst);
+
+ return 0;
+
+err_clamp:
+ clk_disable(clk);
+err_clk:
+ tegra_powergate_power_off(id);
+err_power:
+ return ret;
+}
+EXPORT_SYMBOL(tegra_powergate_sequence_power_up);
+
+static int tegra_powergate_init(void)
+{
+ switch (tegra_get_chiptype()) {
+ case TEGRA20:
+ tegra_num_powerdomains = 7;
+ break;
+ case TEGRA30:
+ tegra_num_powerdomains = 14;
+ break;
+ case TEGRA114:
+ tegra_num_powerdomains = 23;
+ break;
+ case TEGRA124:
+ tegra_num_powerdomains = 25;
+ break;
+ default:
+ /* Unknown Tegra variant. Disable powergating */
+ tegra_num_powerdomains = 0;
+ break;
+ }
+
+ return 0;
+}
+
+static void tegra20_pmc_detect_reset_cause(void)
+{
+ u32 reg = readl(pmc_base + PMC_RST_STATUS);
+
+ switch ((reg & PMC_RST_STATUS_RST_SRC_MASK) >>
+ PMC_RST_STATUS_RST_SRC_SHIFT) {
+ case PMC_RST_STATUS_RST_SRC_POR:
+ reset_source_set(RESET_POR);
+ break;
+ case PMC_RST_STATUS_RST_SRC_WATCHDOG:
+ reset_source_set(RESET_WDG);
+ break;
+ case PMC_RST_STATUS_RST_SRC_LP0:
+ reset_source_set(RESET_WKE);
+ break;
+ case PMC_RST_STATUS_RST_SRC_SW_MAIN:
+ reset_source_set(RESET_RST);
+ break;
+ case PMC_RST_STATUS_RST_SRC_SENSOR:
+ reset_source_set(RESET_THERM);
+ break;
+ default:
+ reset_source_set(RESET_UKWN);
+ break;
+ }
+}
+
static int tegra20_pmc_probe(struct device_d *dev)
{
pmc_base = dev_request_mem_region(dev, 0);
@@ -46,6 +208,11 @@ static int tegra20_pmc_probe(struct device_d *dev)
return PTR_ERR(pmc_base);
}
+ tegra_powergate_init();
+
+ if (IS_ENABLED(CONFIG_RESET_SOURCE))
+ tegra20_pmc_detect_reset_cause();
+
return 0;
}
diff --git a/arch/arm/mach-tegra/tegra20.c b/arch/arm/mach-tegra/tegra20.c
index dcc55aefaa..8d1cd5b2fb 100644
--- a/arch/arm/mach-tegra/tegra20.c
+++ b/arch/arm/mach-tegra/tegra20.c
@@ -22,47 +22,6 @@
#include <mach/lowlevel.h>
#include <mach/tegra114-sysctr.h>
-static struct NS16550_plat debug_uart = {
- .shift = 2,
-};
-
-static int tegra_add_debug_console(void)
-{
- unsigned long base = 0;
-
- if (!of_machine_is_compatible("nvidia,tegra20") &&
- !of_machine_is_compatible("nvidia,tegra30") &&
- !of_machine_is_compatible("nvidia,tegra124"))
- return 0;
-
- /* figure out which UART to use */
- if (IS_ENABLED(CONFIG_TEGRA_UART_NONE))
- return 0;
- if (IS_ENABLED(CONFIG_TEGRA_UART_ODMDATA))
- base = tegra20_get_debuguart_base();
- if (IS_ENABLED(CONFIG_TEGRA_UART_A))
- base = TEGRA_UARTA_BASE;
- if (IS_ENABLED(CONFIG_TEGRA_UART_B))
- base = TEGRA_UARTB_BASE;
- if (IS_ENABLED(CONFIG_TEGRA_UART_C))
- base = TEGRA_UARTC_BASE;
- if (IS_ENABLED(CONFIG_TEGRA_UART_D))
- base = TEGRA_UARTD_BASE;
- if (IS_ENABLED(CONFIG_TEGRA_UART_E))
- base = TEGRA_UARTE_BASE;
-
- if (!base)
- return -ENODEV;
-
- debug_uart.clock = tegra_get_pllp_rate();
-
- add_ns16550_device(DEVICE_ID_DYNAMIC, base, 8 << debug_uart.shift,
- IORESOURCE_MEM | IORESOURCE_MEM_8BIT, &debug_uart);
-
- return 0;
-}
-console_initcall(tegra_add_debug_console);
-
static int tegra20_mem_init(void)
{
if (!of_machine_is_compatible("nvidia,tegra20"))
diff --git a/arch/mips/mach-malta/pci.c b/arch/mips/mach-malta/pci.c
index 90351758e0..47c0e228a7 100644
--- a/arch/mips/mach-malta/pci.c
+++ b/arch/mips/mach-malta/pci.c
@@ -151,7 +151,7 @@ static struct pci_controller gt64120_controller = {
static int pcibios_init(void)
{
- resource_size_t start, end, map, start1, end1, map1, mask, res_end;
+ resource_size_t start, end, map, start1, end1, map1, mask;
/*
* Due to a bug in the Galileo system controller, we need
@@ -207,7 +207,7 @@ static int pcibios_init(void)
BUG_ON((start & GT_PCI_HD_MSK) != (map & GT_PCI_HD_MSK) &&
mask != ~((mask & -mask) - 1));
gt64120_io_resource.start = map & mask;
- res_end = (map & mask) | ~mask;
+ gt64120_io_resource.end = (map & mask) | ~mask;
gt64120_controller.io_offset = 0;
/* Addresses are 36-bit, so do shifts in the destinations. */
gt64120_io_resource.start <<= GT_PCI_DCRM_SHF;
diff --git a/commands/lspci.c b/commands/lspci.c
index fdf02691b5..27edd5d1c2 100644
--- a/commands/lspci.c
+++ b/commands/lspci.c
@@ -20,10 +20,24 @@
#include <complete.h>
#include <linux/pci.h>
+static void traverse_bus(struct pci_bus *bus)
+{
+ struct pci_dev *dev;
+
+ list_for_each_entry(dev, &bus->devices, bus_list) {
+ printf("%02x:%02x.%1x %04x: %04x:%04x (rev %02x)\n",
+ dev->bus->number, PCI_SLOT(dev->devfn),
+ PCI_FUNC(dev->devfn), (dev->class >> 8) & 0xffff,
+ dev->vendor, dev->device, dev->revision);
+
+ if (dev->subordinate)
+ traverse_bus(dev->subordinate);
+ }
+}
+
static int do_lspci(int argc, char *argv[])
{
struct pci_bus *root_bus;
- struct pci_dev *dev;
if (list_empty(&pci_root_buses)) {
printf("No PCI bus detected\n");
@@ -31,14 +45,7 @@ static int do_lspci(int argc, char *argv[])
}
list_for_each_entry(root_bus, &pci_root_buses, node) {
- list_for_each_entry(dev, &root_bus->devices, bus_list) {
- printf("%02x: %04x: %04x:%04x (rev %02x)\n",
- dev->devfn,
- (dev->class >> 8) & 0xffff,
- dev->vendor,
- dev->device,
- dev->revision);
- }
+ traverse_bus(root_bus);
}
return 0;
diff --git a/common/reset_source.c b/common/reset_source.c
index 6026af1967..946670b182 100644
--- a/common/reset_source.c
+++ b/common/reset_source.c
@@ -25,6 +25,7 @@ static const char * const reset_src_names[] = {
[RESET_WDG] = "WDG",
[RESET_WKE] = "WKE",
[RESET_JTAG] = "JTAG",
+ [RESET_THERM] = "THERM",
};
static enum reset_src_type reset_source;
diff --git a/drivers/Kconfig b/drivers/Kconfig
index e126f62c8f..5984ccca2c 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -30,5 +30,6 @@ source "drivers/reset/Kconfig"
source "drivers/pci/Kconfig"
source "drivers/rtc/Kconfig"
source "drivers/firmware/Kconfig"
+source "drivers/phy/Kconfig"
endmenu
diff --git a/drivers/Makefile b/drivers/Makefile
index cf42190b7b..7ef5e90d80 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -29,3 +29,4 @@ obj-$(CONFIG_RESET_CONTROLLER) += reset/
obj-$(CONFIG_PCI) += pci/
obj-y += rtc/
obj-$(CONFIG_FIRMWARE) += firmware/
+obj-$(CONFIG_GENERIC_PHY) += phy/
diff --git a/drivers/clk/tegra/clk-pll.c b/drivers/clk/tegra/clk-pll.c
index c18c67f705..e677effba2 100644
--- a/drivers/clk/tegra/clk-pll.c
+++ b/drivers/clk/tegra/clk-pll.c
@@ -17,12 +17,15 @@
*/
#include <common.h>
+#include <clock.h>
#include <io.h>
#include <malloc.h>
#include <asm-generic/div64.h>
#include <linux/clk.h>
#include <linux/err.h>
+#include <mach/iomap.h>
+
#include "clk.h"
#define PLL_BASE_BYPASS BIT(31)
@@ -60,6 +63,7 @@
#define PLLDU_LFCON_SET_DIVN 600
#define PLLE_BASE_DIVCML_SHIFT 24
+#define PLLE_BASE_DIVCML_MASK 0xf
#define PLLE_BASE_DIVCML_WIDTH 4
#define PLLE_BASE_DIVP_SHIFT 16
#define PLLE_BASE_DIVP_WIDTH 7
@@ -78,8 +82,45 @@
PLLE_MISC_SETUP_EX_MASK)
#define PLLE_MISC_SETUP_VALUE (7 << PLLE_MISC_SETUP_BASE_SHIFT)
-#define PLLE_SS_CTRL 0x68
-#define PLLE_SS_DISABLE (7 << 10)
+#define XUSBIO_PLL_CFG0 0x51c
+#define XUSBIO_PLL_CFG0_PADPLL_RESET_SWCTL (1 << 0)
+#define XUSBIO_PLL_CFG0_CLK_ENABLE_SWCTL (1 << 2)
+#define XUSBIO_PLL_CFG0_PADPLL_USE_LOCKDET (1 << 6)
+#define XUSBIO_PLL_CFG0_SEQ_ENABLE (1 << 24)
+#define XUSBIO_PLL_CFG0_SEQ_START_STATE (1 << 25)
+
+#define PLLE_SS_CTRL 0x68
+#define PLLE_SS_CNTL_BYPASS_SS (7 << 10)
+#define PLLE_SS_CNTL_INTERP_RESET (1 << 11)
+#define PLLE_SS_CNTL_SSC_BYP (1 << 12)
+#define PLLE_SS_CNTL_CENTER (1 << 14)
+#define PLLE_SS_CNTL_INVERT (1 << 15)
+#define PLLE_SS_MAX_MASK 0x1ff
+#define PLLE_SS_MAX_VAL 0x25
+#define PLLE_SS_INC_MASK (0xff << 16)
+#define PLLE_SS_INC_VAL (0x1 << 16)
+#define PLLE_SS_INCINTRV_MASK (0x3f << 24)
+#define PLLE_SS_INCINTRV_VAL (0x20 << 24)
+#define PLLE_SS_COEFFICIENTS_MASK \
+ (PLLE_SS_MAX_MASK | PLLE_SS_INC_MASK | PLLE_SS_INCINTRV_MASK)
+#define PLLE_SS_COEFFICIENTS_VAL \
+ (PLLE_SS_MAX_VAL | PLLE_SS_INC_VAL | PLLE_SS_INCINTRV_VAL)
+
+#define PLLE_MISC_VREG_CTRL_SHIFT 2
+#define PLLE_MISC_VREG_CTRL_MASK (2 << PLLE_MISC_VREG_CTRL_SHIFT)
+#define PLLE_MISC_VREG_BG_CTRL_SHIFT 4
+#define PLLE_MISC_VREG_BG_CTRL_MASK (3 << PLLE_MISC_VREG_BG_CTRL_SHIFT)
+#define PLLE_MISC_PLLE_PTS (1 << 8)
+#define PLLE_MISC_IDDQ_SW_VALUE (1 << 13)
+#define PLLE_MISC_IDDQ_SW_CTRL (1 << 14)
+
+#define PLLE_AUX_PLLP_SEL (1 << 2)
+#define PLLE_AUX_USE_LOCKDET (1 << 3)
+#define PLLE_AUX_ENABLE_SWCTL (1 << 4)
+#define PLLE_AUX_SS_SWCTL (1 << 6)
+#define PLLE_AUX_SEQ_ENABLE (1 << 24)
+#define PLLE_AUX_SEQ_START_STATE (1 << 25)
+#define PLLE_AUX_PLLRE_SEL (1 << 28)
#define PMC_SATA_PWRGT 0x1ac
#define PMC_SATA_PWRGT_PLLE_IDDQ_VALUE BIT(5)
@@ -99,10 +140,19 @@
#define divp_mask(p) (p->flags & TEGRA_PLLU ? PLLU_POST_DIVP_MASK : \
mask(p->divp_width))
+#define divm_shift(p) (p)->divm_shift
+#define divn_shift(p) (p)->divn_shift
+#define divp_shift(p) (p)->divp_shift
+
+#define divm_mask_shifted(p) (divm_mask(p) << divm_shift(p))
+#define divn_mask_shifted(p) (divn_mask(p) << divn_shift(p))
+#define divp_mask_shifted(p) (divp_mask(p) << divp_shift(p))
+
#define divm_max(p) (divm_mask(p))
#define divn_max(p) (divn_mask(p))
#define divp_max(p) (1 << (divp_mask(p)))
+
#define to_clk_pll(_hw) container_of(_hw, struct tegra_clk_pll, hw)
static int clk_pll_is_enabled(struct clk *hw)
@@ -393,6 +443,217 @@ const struct clk_ops tegra_clk_pll_ops = {
.set_rate = clk_pll_set_rate,
};
+static unsigned long clk_plle_recalc_rate(struct clk *hw,
+ unsigned long parent_rate)
+{
+ struct tegra_clk_pll *pll = to_clk_pll(hw);
+ u32 val = pll_readl_base(pll);
+ u32 divn = 0, divm = 0, divp = 0;
+ u64 rate = parent_rate;
+
+ divp = (val >> 16) & 0x3f;
+ divn = (val >> 8) & (0xff);
+ divm = (val >> 0) & (0xff);
+ divm *= divp;
+
+ rate *= divn;
+ do_div(rate, divm);
+ return rate;
+}
+
+static int clk_plle_training(struct tegra_clk_pll *pll)
+{
+ u32 val;
+
+ /*
+ * PLLE is already disabled, and setup cleared;
+ * create falling edge on PLLE IDDQ input.
+ */
+ val = readl(TEGRA_PMC_BASE + PMC_SATA_PWRGT);
+ val |= PMC_SATA_PWRGT_PLLE_IDDQ_VALUE;
+ writel(val, TEGRA_PMC_BASE + PMC_SATA_PWRGT);
+
+ val = readl(TEGRA_PMC_BASE + PMC_SATA_PWRGT);
+ val |= PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL;
+ writel(val, TEGRA_PMC_BASE + PMC_SATA_PWRGT);
+
+ val = readl(TEGRA_PMC_BASE + PMC_SATA_PWRGT);
+ val &= ~PMC_SATA_PWRGT_PLLE_IDDQ_VALUE;
+ writel(val, TEGRA_PMC_BASE + PMC_SATA_PWRGT);
+
+ return wait_on_timeout(100 * MSECOND,
+ (pll_readl_misc(pll) & PLLE_MISC_READY));
+}
+
+static int clk_plle_enable(struct clk *hw)
+{
+ struct tegra_clk_pll *pll = to_clk_pll(hw);
+ unsigned long input_rate = clk_get_rate(clk_get_parent(hw));
+ struct tegra_clk_pll_freq_table sel;
+ u32 val;
+ int err;
+
+ if (_get_table_rate(hw, &sel, pll->fixed_rate, input_rate))
+ return -EINVAL;
+
+ clk_pll_disable(hw);
+
+ val = pll_readl_misc(pll);
+ val &= ~(PLLE_MISC_LOCK_ENABLE | PLLE_MISC_SETUP_MASK);
+ pll_writel_misc(val, pll);
+
+ val = pll_readl_misc(pll);
+ if (!(val & PLLE_MISC_READY)) {
+ err = clk_plle_training(pll);
+ if (err)
+ return err;
+ }
+
+ /* configure dividers */
+ val = pll_readl_base(pll);
+ val &= ~(0x3fffff);
+ val &= ~(PLLE_BASE_DIVCML_WIDTH << PLLE_BASE_DIVCML_SHIFT);
+ val |= sel.m << 0;
+ val |= sel.n << 8;
+ val |= sel.p << 16;
+ val |= sel.cpcon << PLLE_BASE_DIVCML_SHIFT;
+ pll_writel_base(val, pll);
+
+ val = pll_readl_misc(pll);
+ val |= PLLE_MISC_SETUP_VALUE;
+ val |= PLLE_MISC_LOCK_ENABLE;
+ pll_writel_misc(val, pll);
+
+ val = readl(pll->clk_base + PLLE_SS_CTRL);
+ val |= PLLE_SS_CNTL_BYPASS_SS;
+ writel(val, pll->clk_base + PLLE_SS_CTRL);
+
+ val = pll_readl_base(pll);
+ val |= (PLL_BASE_BYPASS | PLL_BASE_ENABLE);
+ pll_writel_base(val, pll);
+
+ clk_pll_wait_for_lock(pll, pll->clk_base + pll->params->base_reg,
+ pll->params->lock_bit_idx);
+
+ return 0;
+}
+
+const struct clk_ops tegra_clk_plle_ops = {
+ .recalc_rate = clk_plle_recalc_rate,
+ .is_enabled = clk_pll_is_enabled,
+ .disable = clk_pll_disable,
+ .enable = clk_plle_enable,
+};
+
+static int clk_plle_tegra114_enable(struct clk *hw)
+{
+ struct tegra_clk_pll *pll = to_clk_pll(hw);
+ unsigned long input_rate = clk_get_rate(clk_get_parent(hw));
+ struct tegra_clk_pll_freq_table sel;
+ u32 val;
+ int ret;
+
+ if (_get_table_rate(hw, &sel, pll->fixed_rate, input_rate))
+ return -EINVAL;
+
+ val = pll_readl_base(pll);
+ val &= ~BIT(29); /* Disable lock override */
+ pll_writel_base(val, pll);
+
+ val = pll_readl(pll->params->aux_reg, pll);
+ val |= PLLE_AUX_ENABLE_SWCTL;
+ val &= ~PLLE_AUX_SEQ_ENABLE;
+ pll_writel(val, pll->params->aux_reg, pll);
+ udelay(1);
+
+ val = pll_readl_misc(pll);
+ val |= PLLE_MISC_LOCK_ENABLE;
+ val |= PLLE_MISC_IDDQ_SW_CTRL;
+ val &= ~PLLE_MISC_IDDQ_SW_VALUE;
+ val |= PLLE_MISC_PLLE_PTS;
+ val |= PLLE_MISC_VREG_BG_CTRL_MASK | PLLE_MISC_VREG_CTRL_MASK;
+ pll_writel_misc(val, pll);
+ udelay(5);
+
+ val = pll_readl(PLLE_SS_CTRL, pll);
+ val |= PLLE_SS_CNTL_BYPASS_SS;
+ pll_writel(val, PLLE_SS_CTRL, pll);
+
+ val = pll_readl_base(pll);
+ val &= ~(divp_mask_shifted(pll) | divn_mask_shifted(pll) |
+ divm_mask_shifted(pll));
+ val &= ~(PLLE_BASE_DIVCML_MASK << PLLE_BASE_DIVCML_SHIFT);
+ val |= sel.m << divm_shift(pll);
+ val |= sel.n << divn_shift(pll);
+ val |= sel.cpcon << PLLE_BASE_DIVCML_SHIFT;
+ pll_writel_base(val, pll);
+ udelay(1);
+
+ clk_pll_enable(hw);
+ ret = clk_pll_wait_for_lock(pll, pll->clk_base + pll->params->misc_reg,
+ pll->params->lock_bit_idx);
+
+ if (ret < 0)
+ return ret;
+
+ val = pll_readl(PLLE_SS_CTRL, pll);
+ val &= ~(PLLE_SS_CNTL_CENTER | PLLE_SS_CNTL_INVERT);
+ val &= ~PLLE_SS_COEFFICIENTS_MASK;
+ val |= PLLE_SS_COEFFICIENTS_VAL;
+ pll_writel(val, PLLE_SS_CTRL, pll);
+ val &= ~(PLLE_SS_CNTL_SSC_BYP | PLLE_SS_CNTL_BYPASS_SS);
+ pll_writel(val, PLLE_SS_CTRL, pll);
+ udelay(1);
+ val &= ~PLLE_SS_CNTL_INTERP_RESET;
+ pll_writel(val, PLLE_SS_CTRL, pll);
+ udelay(1);
+
+ /* Enable hw control of xusb brick pll */
+ val = pll_readl_misc(pll);
+ val &= ~PLLE_MISC_IDDQ_SW_CTRL;
+ pll_writel_misc(val, pll);
+
+ val = pll_readl(pll->params->aux_reg, pll);
+ val |= (PLLE_AUX_USE_LOCKDET | PLLE_AUX_SEQ_START_STATE);
+ val &= ~(PLLE_AUX_ENABLE_SWCTL | PLLE_AUX_SS_SWCTL);
+ pll_writel(val, pll->params->aux_reg, pll);
+ udelay(1);
+ val |= PLLE_AUX_SEQ_ENABLE;
+ pll_writel(val, pll->params->aux_reg, pll);
+
+ val = pll_readl(XUSBIO_PLL_CFG0, pll);
+ val |= (XUSBIO_PLL_CFG0_PADPLL_USE_LOCKDET |
+ XUSBIO_PLL_CFG0_SEQ_START_STATE);
+ val &= ~(XUSBIO_PLL_CFG0_CLK_ENABLE_SWCTL |
+ XUSBIO_PLL_CFG0_PADPLL_RESET_SWCTL);
+ pll_writel(val, XUSBIO_PLL_CFG0, pll);
+ udelay(1);
+ val |= XUSBIO_PLL_CFG0_SEQ_ENABLE;
+ pll_writel(val, XUSBIO_PLL_CFG0, pll);
+
+ return ret;
+}
+
+static void clk_plle_tegra114_disable(struct clk *hw)
+{
+ struct tegra_clk_pll *pll = to_clk_pll(hw);
+ u32 val;
+
+ clk_pll_disable(hw);
+
+ val = pll_readl_misc(pll);
+ val |= PLLE_MISC_IDDQ_SW_CTRL | PLLE_MISC_IDDQ_SW_VALUE;
+ pll_writel_misc(val, pll);
+ udelay(1);
+}
+
+const struct clk_ops tegra_clk_plle_tegra114_ops = {
+ .recalc_rate = clk_pll_recalc_rate,
+ .is_enabled = clk_pll_is_enabled,
+ .disable = clk_plle_tegra114_disable,
+ .enable = clk_plle_tegra114_enable,
+};
+
static struct clk *_tegra_clk_register_pll(const char *name,
const char *parent_name, void __iomem *clk_base,
unsigned long flags, unsigned long fixed_rate,
@@ -447,3 +708,25 @@ struct clk *tegra_clk_register_pll(const char *name, const char *parent_name,
flags, fixed_rate, pll_params, pll_flags, freq_table,
&tegra_clk_pll_ops);
}
+
+struct clk *tegra_clk_register_plle(const char *name, const char *parent_name,
+ void __iomem *clk_base,
+ unsigned long flags, unsigned long fixed_rate,
+ struct tegra_clk_pll_params *pll_params, u8 pll_flags,
+ struct tegra_clk_pll_freq_table *freq_table)
+{
+ return _tegra_clk_register_pll(name, parent_name, clk_base,
+ flags, fixed_rate, pll_params, pll_flags, freq_table,
+ &tegra_clk_plle_ops);
+}
+
+struct clk *tegra_clk_register_plle_tegra114(const char *name,
+ const char *parent_name, void __iomem *clk_base,
+ unsigned long flags, unsigned long fixed_rate,
+ struct tegra_clk_pll_params *pll_params, u8 pll_flags,
+ struct tegra_clk_pll_freq_table *freq_table)
+{
+ return _tegra_clk_register_pll(name, parent_name, clk_base,
+ flags, fixed_rate, pll_params, pll_flags, freq_table,
+ &tegra_clk_plle_tegra114_ops);
+}
diff --git a/drivers/clk/tegra/clk-tegra124.c b/drivers/clk/tegra/clk-tegra124.c
index 514b22a784..7a2f7c081f 100644
--- a/drivers/clk/tegra/clk-tegra124.c
+++ b/drivers/clk/tegra/clk-tegra124.c
@@ -62,6 +62,15 @@ static struct tegra_clk_pll_freq_table pll_c_freq_table[] = {
{ 0, 0, 0, 0, 0, 0 },
};
+static struct tegra_clk_pll_freq_table pll_e_freq_table[] = {
+ /* PLLE special case: use cpcon field to store cml divider value */
+ {336000000, 100000000, 100, 21, 16, 11},
+ {312000000, 100000000, 200, 26, 24, 13},
+ {13000000, 100000000, 200, 1, 26, 13},
+ {12000000, 100000000, 200, 1, 24, 13},
+ {0, 0, 0, 0, 0, 0},
+};
+
static struct tegra_clk_pll_freq_table pll_p_freq_table[] = {
{12000000, 408000000, 408, 12, 0, 8},
{13000000, 408000000, 408, 13, 0, 8},
@@ -114,6 +123,21 @@ static struct tegra_clk_pll_params pll_c_params = {
.lock_delay = 300,
};
+static struct tegra_clk_pll_params pll_e_params = {
+ .input_min = 12000000,
+ .input_max = 1000000000,
+ .cf_min = 12000000,
+ .cf_max = 75000000,
+ .vco_min = 1600000000,
+ .vco_max = 2400000000U,
+ .base_reg = CRC_PLLE_BASE,
+ .misc_reg = CRC_PLLE_MISC,
+ .aux_reg = CRC_PLLE_AUX,
+ .lock_bit_idx = CRC_PLLE_MISC_LOCK,
+ .lock_enable_bit_idx = CRC_PLLE_MISC_LOCK_ENABLE,
+ .lock_delay = 300,
+};
+
static struct tegra_clk_pll_params pll_p_params = {
.input_min = 2000000,
.input_max = 31000000,
@@ -220,6 +244,11 @@ static void tegra124_pll_init(void)
clks[TEGRA124_CLK_PLL_U] = tegra_clk_register_pll("pll_u", "pll_ref",
car_base, 0, 0, &pll_u_params, TEGRA_PLLU |
TEGRA_PLL_HAS_CPCON, pll_u_freq_table);
+
+ /* PLLE */
+ clks[TEGRA124_CLK_PLL_E] = tegra_clk_register_plle_tegra114("pll_e",
+ "pll_ref", car_base, 0, 100000000, &pll_e_params,
+ TEGRA_PLL_FIXED | TEGRA_PLL_USE_LOCK, pll_e_freq_table);
}
static const char *mux_pllpcm_clkm[] = {"pll_p", "pll_c2", "pll_c", "pll_c3",
@@ -244,6 +273,12 @@ static void tegra124_periph_init(void)
mux_pllpcm_clkm, ARRAY_SIZE(mux_pllpcm_clkm), car_base,
CRC_CLK_SOURCE_UARTD, TEGRA124_CLK_UARTD,
TEGRA_PERIPH_ON_APB);
+ clks[TEGRA124_CLK_PCIE] = clk_gate("pcie", "clk_m",
+ car_base + CRC_CLK_OUT_ENB_U, 6, 0, 0);
+ clks[TEGRA124_CLK_AFI] = clk_gate("afi", "clk_m",
+ car_base + CRC_CLK_OUT_ENB_U, 8, 0, 0);
+ clks[TEGRA124_CLK_CML0] = clk_gate("cml0", "pll_e",
+ car_base + CRC_PLLE_AUX, 0, 0, 0);
/* peripheral clocks with a divider */
clks[TEGRA124_CLK_MSELECT] = tegra_clk_register_periph("mselect",
@@ -286,11 +321,11 @@ static struct tegra_clk_init_table init_table[] = {
{TEGRA124_CLK_PLL_P_OUT2, TEGRA124_CLK_CLK_MAX, 48000000, 1},
{TEGRA124_CLK_PLL_P_OUT3, TEGRA124_CLK_CLK_MAX, 102000000, 1},
{TEGRA124_CLK_PLL_P_OUT4, TEGRA124_CLK_CLK_MAX, 204000000, 1},
- {TEGRA124_CLK_MSELECT, TEGRA124_CLK_PLL_P, 204000000, 1},
- {TEGRA124_CLK_UARTA, TEGRA124_CLK_PLL_P, 0, 1},
- {TEGRA124_CLK_UARTB, TEGRA124_CLK_PLL_P, 0, 1},
- {TEGRA124_CLK_UARTC, TEGRA124_CLK_PLL_P, 0, 1},
- {TEGRA124_CLK_UARTD, TEGRA124_CLK_PLL_P, 0, 1},
+ {TEGRA124_CLK_MSELECT, TEGRA124_CLK_PLL_P, 102000000, 1},
+ {TEGRA124_CLK_UARTA, TEGRA124_CLK_PLL_P, 0, 0},
+ {TEGRA124_CLK_UARTB, TEGRA124_CLK_PLL_P, 0, 0},
+ {TEGRA124_CLK_UARTC, TEGRA124_CLK_PLL_P, 0, 0},
+ {TEGRA124_CLK_UARTD, TEGRA124_CLK_PLL_P, 0, 0},
{TEGRA124_CLK_SDMMC1, TEGRA124_CLK_PLL_P, 48000000, 0},
{TEGRA124_CLK_SDMMC2, TEGRA124_CLK_PLL_P, 48000000, 0},
{TEGRA124_CLK_SDMMC3, TEGRA124_CLK_PLL_P, 48000000, 0},
diff --git a/drivers/clk/tegra/clk-tegra20.c b/drivers/clk/tegra/clk-tegra20.c
index 5b4365d492..2ff42d8bdb 100644
--- a/drivers/clk/tegra/clk-tegra20.c
+++ b/drivers/clk/tegra/clk-tegra20.c
@@ -324,11 +324,11 @@ static struct tegra_clk_init_table init_table[] = {
{TEGRA20_CLK_PLL_P_OUT4, TEGRA20_CLK_CLK_MAX, 24000000, 1},
{TEGRA20_CLK_PLL_C, TEGRA20_CLK_CLK_MAX, 600000000, 1},
{TEGRA20_CLK_PLL_C_OUT1, TEGRA20_CLK_CLK_MAX, 120000000, 1},
- {TEGRA20_CLK_UARTA, TEGRA20_CLK_PLL_P, 0, 1},
- {TEGRA20_CLK_UARTB, TEGRA20_CLK_PLL_P, 0, 1},
- {TEGRA20_CLK_UARTC, TEGRA20_CLK_PLL_P, 0, 1},
- {TEGRA20_CLK_UARTD, TEGRA20_CLK_PLL_P, 0, 1},
- {TEGRA20_CLK_UARTE, TEGRA20_CLK_PLL_P, 0, 1},
+ {TEGRA20_CLK_UARTA, TEGRA20_CLK_PLL_P, 0, 0},
+ {TEGRA20_CLK_UARTB, TEGRA20_CLK_PLL_P, 0, 0},
+ {TEGRA20_CLK_UARTC, TEGRA20_CLK_PLL_P, 0, 0},
+ {TEGRA20_CLK_UARTD, TEGRA20_CLK_PLL_P, 0, 0},
+ {TEGRA20_CLK_UARTE, TEGRA20_CLK_PLL_P, 0, 0},
{TEGRA20_CLK_SDMMC1, TEGRA20_CLK_PLL_P, 48000000, 0},
{TEGRA20_CLK_SDMMC2, TEGRA20_CLK_PLL_P, 48000000, 0},
{TEGRA20_CLK_SDMMC3, TEGRA20_CLK_PLL_P, 48000000, 0},
diff --git a/drivers/clk/tegra/clk-tegra30.c b/drivers/clk/tegra/clk-tegra30.c
index ed6d73625c..46fd6dddea 100644
--- a/drivers/clk/tegra/clk-tegra30.c
+++ b/drivers/clk/tegra/clk-tegra30.c
@@ -130,6 +130,13 @@ static struct tegra_clk_pll_freq_table pll_u_freq_table[] = {
{ 0, 0, 0, 0, 0, 0 },
};
+static struct tegra_clk_pll_freq_table pll_e_freq_table[] = {
+ /* PLLE special case: use cpcon field to store cml divider value */
+ { 12000000, 100000000, 150, 1, 18, 11},
+ { 216000000, 100000000, 200, 18, 24, 13},
+ { 0, 0, 0, 0, 0, 0 },
+};
+
/* PLL parameters */
static struct tegra_clk_pll_params pll_c_params = {
.input_min = 2000000,
@@ -201,6 +208,19 @@ static struct tegra_clk_pll_params pll_u_params = {
.lock_delay = 1000,
};
+static struct tegra_clk_pll_params pll_e_params = {
+ .input_min = 12000000,
+ .input_max = 216000000,
+ .cf_min = 12000000,
+ .cf_max = 12000000,
+ .vco_min = 1200000000,
+ .vco_max = 2400000000U,
+ .base_reg = CRC_PLLE_BASE,
+ .misc_reg = CRC_PLLE_MISC,
+ .lock_enable_bit_idx = CRC_PLLE_MISC_LOCK_ENABLE,
+ .lock_delay = 300,
+};
+
static void tegra30_pll_init(void)
{
/* PLLC */
@@ -251,6 +271,11 @@ static void tegra30_pll_init(void)
clks[TEGRA30_CLK_PLL_U] = tegra_clk_register_pll("pll_u", "pll_ref",
car_base, 0, 0, &pll_u_params, TEGRA_PLLU |
TEGRA_PLL_HAS_CPCON, pll_u_freq_table);
+
+ /* PLLE */
+ clks[TEGRA30_CLK_PLL_E] = tegra_clk_register_plle("pll_e", "pll_ref",
+ car_base, 0, 100000000, &pll_e_params,
+ TEGRA_PLL_FIXED | TEGRA_PLL_USE_LOCK, pll_e_freq_table);
}
static const char *mux_pllpcm_clkm[] = {"pll_p", "pll_c", "pll_m", "clk_m"};
@@ -278,6 +303,12 @@ static void tegra30_periph_init(void)
mux_pllpcm_clkm, ARRAY_SIZE(mux_pllpcm_clkm), car_base,
CRC_CLK_SOURCE_UARTE, TEGRA30_CLK_UARTE,
TEGRA_PERIPH_ON_APB);
+ clks[TEGRA30_CLK_PCIE] = clk_gate("pcie", "clk_m",
+ car_base + CRC_CLK_OUT_ENB_U, 6, 0, 0);
+ clks[TEGRA30_CLK_AFI] = clk_gate("afi", "clk_m",
+ car_base + CRC_CLK_OUT_ENB_U, 8, 0, 0);
+ clks[TEGRA30_CLK_CML0] = clk_gate("cml0", "pll_e",
+ car_base + CRC_PLLE_AUX, 0, 0, 0);
/* peripheral clocks with a divider */
clks[TEGRA30_CLK_MSELECT] = tegra_clk_register_periph("mselect",
@@ -320,12 +351,12 @@ static struct tegra_clk_init_table init_table[] = {
{TEGRA30_CLK_PLL_P_OUT2, TEGRA30_CLK_CLK_MAX, 48000000, 1},
{TEGRA30_CLK_PLL_P_OUT3, TEGRA30_CLK_CLK_MAX, 102000000, 1},
{TEGRA30_CLK_PLL_P_OUT4, TEGRA30_CLK_CLK_MAX, 204000000, 1},
- {TEGRA30_CLK_MSELECT, TEGRA30_CLK_PLL_P, 204000000, 1},
- {TEGRA30_CLK_UARTA, TEGRA30_CLK_PLL_P, 0, 1},
- {TEGRA30_CLK_UARTB, TEGRA30_CLK_PLL_P, 0, 1},
- {TEGRA30_CLK_UARTC, TEGRA30_CLK_PLL_P, 0, 1},
- {TEGRA30_CLK_UARTD, TEGRA30_CLK_PLL_P, 0, 1},
- {TEGRA30_CLK_UARTE, TEGRA30_CLK_PLL_P, 0, 1},
+ {TEGRA30_CLK_MSELECT, TEGRA30_CLK_PLL_P, 102000000, 1},
+ {TEGRA30_CLK_UARTA, TEGRA30_CLK_PLL_P, 0, 0},
+ {TEGRA30_CLK_UARTB, TEGRA30_CLK_PLL_P, 0, 0},
+ {TEGRA30_CLK_UARTC, TEGRA30_CLK_PLL_P, 0, 0},
+ {TEGRA30_CLK_UARTD, TEGRA30_CLK_PLL_P, 0, 0},
+ {TEGRA30_CLK_UARTE, TEGRA30_CLK_PLL_P, 0, 0},
{TEGRA30_CLK_SDMMC1, TEGRA30_CLK_PLL_P, 48000000, 0},
{TEGRA30_CLK_SDMMC2, TEGRA30_CLK_PLL_P, 48000000, 0},
{TEGRA30_CLK_SDMMC3, TEGRA30_CLK_PLL_P, 48000000, 0},
diff --git a/drivers/clk/tegra/clk.h b/drivers/clk/tegra/clk.h
index d5d0730602..10d03573fd 100644
--- a/drivers/clk/tegra/clk.h
+++ b/drivers/clk/tegra/clk.h
@@ -63,6 +63,7 @@ struct tegra_clk_pll_params {
u32 base_reg;
u32 misc_reg;
+ u32 aux_reg;
u32 lock_reg;
u8 lock_bit_idx;
u8 lock_enable_bit_idx;
@@ -101,6 +102,18 @@ struct clk *tegra_clk_register_pll(const char *name, const char *parent_name,
struct tegra_clk_pll_params *pll_params, u8 pll_flags,
struct tegra_clk_pll_freq_table *freq_table);
+struct clk *tegra_clk_register_plle(const char *name, const char *parent_name,
+ void __iomem *clk_base,
+ unsigned long flags, unsigned long fixed_rate,
+ struct tegra_clk_pll_params *pll_params, u8 pll_flags,
+ struct tegra_clk_pll_freq_table *freq_table);
+
+struct clk *tegra_clk_register_plle_tegra114(const char *name,
+ const char *parent_name, void __iomem *clk_base,
+ unsigned long flags, unsigned long fixed_rate,
+ struct tegra_clk_pll_params *pll_params, u8 pll_flags,
+ struct tegra_clk_pll_freq_table *freq_table);
+
/* struct tegra_clk_pll_out - PLL output divider */
struct tegra_clk_pll_out {
struct clk hw;
diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c
index c52da18b57..f793cbeabf 100644
--- a/drivers/i2c/busses/i2c-tegra.c
+++ b/drivers/i2c/busses/i2c-tegra.c
@@ -696,4 +696,4 @@ static struct driver_d tegra_i2c_driver = {
.probe = tegra_i2c_probe,
.of_compatible = DRV_OF_COMPAT(tegra_i2c_compatible),
};
-device_platform_driver(tegra_i2c_driver);
+register_driver_macro(fs, platform, tegra_i2c_driver);
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index c99fcc8316..24b984462d 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -156,6 +156,14 @@ config DRIVER_NET_RTL8139
This is a driver for the Fast Ethernet PCI network cards based on
the RTL 8139 chips.
+config DRIVER_NET_RTL8169
+ bool "RealTek RTL-8169 PCI Ethernet driver"
+ depends on PCI
+ select PHYLIB
+ help
+ This is a driver for the Fast Ethernet PCI network cards based on
+ the RTL 8169 chips.
+
config DRIVER_NET_SMC911X
bool "smc911x ethernet driver"
select PHYLIB
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 1b85778f9f..3e66b3135c 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -22,6 +22,7 @@ obj-$(CONFIG_DRIVER_NET_MPC5200) += fec_mpc5200.o
obj-$(CONFIG_DRIVER_NET_NETX) += netx_eth.o
obj-$(CONFIG_DRIVER_NET_ORION) += orion-gbe.o
obj-$(CONFIG_DRIVER_NET_RTL8139) += rtl8139.o
+obj-$(CONFIG_DRIVER_NET_RTL8169) += rtl8169.o
obj-$(CONFIG_DRIVER_NET_SMC911X) += smc911x.o
obj-$(CONFIG_DRIVER_NET_SMC91111) += smc91111.o
obj-$(CONFIG_DRIVER_NET_TAP) += tap.o
diff --git a/drivers/net/rtl8169.c b/drivers/net/rtl8169.c
new file mode 100644
index 0000000000..5702900e49
--- /dev/null
+++ b/drivers/net/rtl8169.c
@@ -0,0 +1,578 @@
+/*
+ * Copyright (C) 2014 Lucas Stach <l.stach@pengutronix.de>
+ *
+ * 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 <asm/mmu.h>
+#include <common.h>
+#include <init.h>
+#include <net.h>
+#include <malloc.h>
+#include <linux/pci.h>
+
+#define NUM_TX_DESC 1
+#define NUM_RX_DESC 4
+#define PKT_BUF_SIZE 1536
+#define ETH_ZLEN 60
+
+struct rtl8169_chip_info {
+ const char *name;
+ u8 version;
+ u32 RxConfigMask;
+};
+
+#define BD_STAT_OWN 0x80000000
+#define BD_STAT_EOR 0x40000000
+#define BD_STAT_FS 0x20000000
+#define BD_STAT_LS 0x10000000
+#define BD_STAT_RX_RES 0x00200000
+struct bufdesc {
+ u32 status;
+ u32 vlan_tag;
+ u32 buf_addr;
+ u32 buf_Haddr;
+};
+
+struct rtl8169_priv {
+ struct eth_device edev;
+ void __iomem *base;
+ struct pci_dev *pci_dev;
+ int chipset;
+
+ struct bufdesc *tx_desc;
+ void *tx_buf;
+ unsigned int cur_tx;
+
+ struct bufdesc *rx_desc;
+ void *rx_buf;
+ unsigned int cur_rx;
+
+ struct mii_bus miibus;
+};
+
+#define MAC0 0x00
+#define MAR0 0x08
+#define TxDescStartAddrLow 0x20
+#define TxDescStartAddrHigh 0x24
+#define TxHDescStartAddrLow 0x28
+#define TxHDescStartAddrHigh 0x2c
+#define FLASH 0x30
+#define ERSR 0x36
+#define ChipCmd 0x37
+#define CmdReset 0x10
+#define CmdRxEnb 0x08
+#define CmdTxEnb 0x04
+#define RxBufEmpty 0x01
+#define TxPoll 0x38
+#define IntrMask 0x3c
+#define IntrStatus 0x3e
+#define SYSErr 0x8000
+#define PCSTimeout 0x4000
+#define SWInt 0x0100
+#define TxDescUnavail 0x80
+#define RxFIFOOver 0x40
+#define RxUnderrun 0x20
+#define RxOverflow 0x10
+#define TxErr 0x08
+#define TxOK 0x04
+#define RxErr 0x02
+#define RxOK 0x01
+#define TxConfig 0x40
+#define TxInterFrameGapShift 24
+#define TxDMAShift 8
+#define RxConfig 0x44
+#define AcceptErr 0x20
+#define AcceptRunt 0x10
+#define AcceptBroadcast 0x08
+#define AcceptMulticast 0x04
+#define AcceptMyPhys 0x02
+#define AcceptAllPhys 0x01
+#define RxCfgFIFOShift 13
+#define RxCfgDMAShift 8
+#define RxMissed 0x4c
+#define Cfg9346 0x50
+#define Cfg9346_Lock 0x00
+#define Cfg9346_Unlock 0xc0
+#define Config0 0x51
+#define Config1 0x52
+#define Config2 0x53
+#define Config3 0x54
+#define Config4 0x55
+#define Config5 0x56
+#define MultiIntr 0x5c
+#define PHYAR 0x60
+#define TBICSR 0x64
+#define TBI_ANAR 0x68
+#define TBI_LPAR 0x6a
+#define PHYstatus 0x6c
+#define RxMaxSize 0xda
+#define CPlusCmd 0xe0
+#define RxDescStartAddrLow 0xe4
+#define RxDescStartAddrHigh 0xe8
+#define EarlyTxThres 0xec
+#define FuncEvent 0xf0
+#define FuncEventMask 0xf4
+#define FuncPresetState 0xf8
+#define FuncForceEvent 0xfc
+
+/* write MMIO register */
+#define RTL_W8(priv, reg, val) writeb(val, ((char *)(priv->base) + reg))
+#define RTL_W16(priv, reg, val) writew(val, ((char *)(priv->base) + reg))
+#define RTL_W32(priv, reg, val) writel(val, ((char *)(priv->base) + reg))
+
+/* read MMIO register */
+#define RTL_R8(priv, reg) readb(((char *)(priv->base) + reg))
+#define RTL_R16(priv, reg) readw(((char *)(priv->base) + reg))
+#define RTL_R32(priv, reg) readl(((char *)(priv->base) + reg))
+
+static const u32 rtl8169_rx_config =
+ (7 << RxCfgFIFOShift) | (6 << RxCfgDMAShift);
+
+static void rtl8169_chip_reset(struct rtl8169_priv *priv)
+{
+ int i;
+
+ /* Soft reset the chip. */
+ RTL_W8(priv, ChipCmd, CmdReset);
+
+ /* Check that the chip has finished the reset. */
+ for (i = 1000; i > 0; i--) {
+ if ((RTL_R8(priv, ChipCmd) & CmdReset) == 0)
+ break;
+ udelay(10);
+ }
+}
+
+static struct rtl8169_chip_info chip_info[] = {
+ {"RTL-8169", 0x00, 0xff7e1880},
+ {"RTL-8169", 0x04, 0xff7e1880},
+ {"RTL-8169", 0x00, 0xff7e1880},
+ {"RTL-8169s/8110s", 0x02, 0xff7e1880},
+ {"RTL-8169s/8110s", 0x04, 0xff7e1880},
+ {"RTL-8169sb/8110sb", 0x10, 0xff7e1880},
+ {"RTL-8169sc/8110sc", 0x18, 0xff7e1880},
+ {"RTL-8168b/8111sb", 0x30, 0xff7e1880},
+ {"RTL-8168b/8111sb", 0x38, 0xff7e1880},
+ {"RTL-8168d/8111d", 0x28, 0xff7e1880},
+ {"RTL-8168evl/8111evl", 0x2e, 0xff7e1880},
+ {"RTL-8168/8111g", 0x4c, 0xff7e1880,},
+ {"RTL-8101e", 0x34, 0xff7e1880},
+ {"RTL-8100e", 0x32, 0xff7e1880},
+};
+
+static void rtl8169_chip_identify(struct rtl8169_priv *priv)
+{
+ u32 val;
+ int i;
+
+ val = RTL_R32(priv, TxConfig);
+ val = ((val & 0x7c000000) + ((val & 0x00800000) << 2)) >> 24;
+
+ for (i = ARRAY_SIZE(chip_info) - 1; i >= 0; i--){
+ if (val == chip_info[i].version) {
+ priv->chipset = i;
+ dev_dbg(&priv->pci_dev->dev, "found %s chipset\n",
+ chip_info[i].name);
+ return;
+ }
+ }
+
+ dev_dbg(&priv->pci_dev->dev,
+ "no matching chip version found, assuming RTL-8169\n");
+ priv->chipset = 0;
+}
+
+static int rtl8169_init_dev(struct eth_device *edev)
+{
+ struct rtl8169_priv *priv = edev->priv;
+
+ rtl8169_chip_reset(priv);
+ rtl8169_chip_identify(priv);
+ pci_set_master(priv->pci_dev);
+
+ return 0;
+}
+
+static void __set_rx_mode(struct rtl8169_priv *priv)
+{
+ u32 mc_filter[2], val;
+
+ /* IFF_ALLMULTI */
+ /* Too many to filter perfectly -- accept all multicasts. */
+ mc_filter[1] = mc_filter[0] = 0xffffffff;
+
+ val = AcceptBroadcast | AcceptMulticast | AcceptMyPhys |
+ rtl8169_rx_config | (RTL_R32(priv, RxConfig) &
+ chip_info[priv->chipset].RxConfigMask);
+
+ RTL_W32(priv, RxConfig, val);
+ RTL_W32(priv, MAR0 + 0, mc_filter[0]);
+ RTL_W32(priv, MAR0 + 4, mc_filter[1]);
+}
+
+static void rtl8169_init_ring(struct rtl8169_priv *priv)
+{
+ int i;
+
+ priv->cur_rx = priv->cur_tx = 0;
+
+ priv->tx_desc = dma_alloc_coherent(NUM_TX_DESC *
+ sizeof(struct bufdesc));
+ priv->tx_buf = malloc(NUM_TX_DESC * PKT_BUF_SIZE);
+ priv->rx_desc = dma_alloc_coherent(NUM_RX_DESC *
+ sizeof(struct bufdesc));
+ priv->rx_buf = malloc(NUM_RX_DESC * PKT_BUF_SIZE);
+ dma_clean_range((unsigned long)priv->rx_buf,
+ (unsigned long)priv->rx_buf + NUM_RX_DESC * PKT_BUF_SIZE);
+
+ memset(priv->tx_desc, 0, NUM_TX_DESC * sizeof(struct bufdesc));
+ memset(priv->rx_desc, 0, NUM_RX_DESC * sizeof(struct bufdesc));
+
+ for (i = 0; i < NUM_RX_DESC; i++) {
+ if (i == (NUM_RX_DESC - 1))
+ priv->rx_desc[i].status =
+ BD_STAT_OWN | BD_STAT_EOR | PKT_BUF_SIZE;
+ else
+ priv->rx_desc[i].status =
+ BD_STAT_OWN | PKT_BUF_SIZE;
+
+ priv->rx_desc[i].buf_addr =
+ virt_to_phys(priv->rx_buf + i * PKT_BUF_SIZE);
+ }
+
+ dma_flush_range((unsigned long)priv->rx_desc,
+ (unsigned long)priv->rx_desc +
+ NUM_RX_DESC * sizeof(struct bufdesc));
+}
+
+static void rtl8169_hw_start(struct rtl8169_priv *priv)
+{
+ u32 val;
+
+ RTL_W8(priv, Cfg9346, Cfg9346_Unlock);
+
+ /* RTL-8169sb/8110sb or previous version */
+ if (priv->chipset <= 5)
+ RTL_W8(priv, ChipCmd, CmdTxEnb | CmdRxEnb);
+
+ RTL_W8(priv, EarlyTxThres, 0x3f);
+
+ /* For gigabit rtl8169 */
+ RTL_W16(priv, RxMaxSize, 0x800);
+
+ /* Set Rx Config register */
+ val = rtl8169_rx_config | (RTL_R32(priv, RxConfig) &
+ chip_info[priv->chipset].RxConfigMask);
+ RTL_W32(priv, RxConfig, val);
+
+ /* Set DMA burst size and Interframe Gap Time */
+ RTL_W32(priv, TxConfig, (6 << TxDMAShift) | (3 << TxInterFrameGapShift));
+
+ RTL_W32(priv, TxDescStartAddrLow, virt_to_phys(priv->tx_desc));
+ RTL_W32(priv, TxDescStartAddrHigh, 0);
+ RTL_W32(priv, RxDescStartAddrLow, virt_to_phys(priv->rx_desc));
+ RTL_W32(priv, RxDescStartAddrHigh, 0);
+
+ /* RTL-8169sc/8110sc or later version */
+ if (priv->chipset > 5)
+ RTL_W8(priv, ChipCmd, CmdTxEnb | CmdRxEnb);
+
+ RTL_W8(priv, Cfg9346, Cfg9346_Lock);
+ udelay(10);
+
+ RTL_W32(priv, RxMissed, 0);
+
+ __set_rx_mode(priv);
+
+ /* no early-rx interrupts */
+ RTL_W16(priv, MultiIntr, RTL_R16(priv, MultiIntr) & 0xf000);
+}
+
+static int rtl8169_eth_open(struct eth_device *edev)
+{
+ struct rtl8169_priv *priv = edev->priv;
+ int ret;
+
+ rtl8169_init_ring(priv);
+ rtl8169_hw_start(priv);
+
+ ret = phy_device_connect(edev, &priv->miibus, 0, NULL, 0,
+ PHY_INTERFACE_MODE_NA);
+
+ return ret;
+}
+
+static int rtl8169_phy_write(struct mii_bus *bus, int phy_addr,
+ int reg, u16 val)
+{
+ struct rtl8169_priv *priv = bus->priv;
+ int i;
+
+ if (phy_addr != 0)
+ return -1;
+
+ RTL_W32(priv, PHYAR, 0x80000000 | (reg & 0xff) << 16 | val);
+ mdelay(1);
+
+ for (i = 2000; i > 0; i--) {
+ if (!(RTL_R32(priv, PHYAR) & 0x80000000)) {
+ return 0;
+ } else {
+ udelay(100);
+ }
+ }
+
+ return -1;
+}
+
+static int rtl8169_phy_read(struct mii_bus *bus, int phy_addr, int reg)
+{
+ struct rtl8169_priv *priv = bus->priv;
+ int i, val = 0xffff;
+
+ RTL_W32(priv, PHYAR, 0x0 | (reg & 0xff) << 16);
+ mdelay(10);
+
+ if (phy_addr != 0)
+ return val;
+
+ for (i = 2000; i > 0; i--) {
+ if (RTL_R32(priv, PHYAR) & 0x80000000) {
+ val = (int) (RTL_R32(priv, PHYAR) & 0xffff);
+ break;
+ } else {
+ udelay(100);
+ }
+ }
+ return val;
+}
+
+static int rtl8169_eth_send(struct eth_device *edev, void *packet,
+ int packet_length)
+{
+ struct rtl8169_priv *priv = edev->priv;
+ unsigned int entry;
+
+ entry = priv->cur_tx % NUM_TX_DESC;
+
+ if (packet_length < ETH_ZLEN)
+ memset(priv->tx_buf + entry * PKT_BUF_SIZE, 0, ETH_ZLEN);
+ memcpy(priv->tx_buf + entry * PKT_BUF_SIZE, packet, packet_length);
+ dma_flush_range((unsigned long)priv->tx_buf + entry * PKT_BUF_SIZE,
+ (unsigned long)priv->tx_buf + (entry + 1) * PKT_BUF_SIZE);
+
+ priv->tx_desc[entry].buf_Haddr = 0;
+ priv->tx_desc[entry].buf_addr =
+ virt_to_phys(priv->tx_buf + entry * PKT_BUF_SIZE);
+
+ if (entry != (NUM_TX_DESC - 1)) {
+ priv->tx_desc[entry].status =
+ BD_STAT_OWN | BD_STAT_FS | BD_STAT_LS |
+ ((packet_length > ETH_ZLEN) ? packet_length : ETH_ZLEN);
+ } else {
+ priv->tx_desc[entry].status =
+ BD_STAT_OWN | BD_STAT_EOR | BD_STAT_FS | BD_STAT_LS |
+ ((packet_length > ETH_ZLEN) ? packet_length : ETH_ZLEN);
+ }
+
+ dma_flush_range((unsigned long)&priv->tx_desc[entry],
+ (unsigned long)&priv->tx_desc[entry + 1]);
+
+ RTL_W8(priv, TxPoll, 0x40);
+ do {
+ dma_inv_range((unsigned long)&priv->tx_desc[entry],
+ (unsigned long)&priv->tx_desc[entry + 1]);
+ } while (priv->tx_desc[entry].status & BD_STAT_OWN);
+
+ priv->cur_tx++;
+
+ return 0;
+}
+
+static int rtl8169_eth_rx(struct eth_device *edev)
+{
+ struct rtl8169_priv *priv = edev->priv;
+ unsigned int entry, pkt_size = 0;
+ u8 status;
+
+ entry = priv->cur_rx % NUM_RX_DESC;
+
+ dma_inv_range((unsigned long)&priv->rx_desc[entry],
+ (unsigned long)&priv->rx_desc[entry + 1]);
+
+ if ((priv->rx_desc[entry].status & BD_STAT_OWN) == 0) {
+ if (!(priv->rx_desc[entry].status & BD_STAT_RX_RES)) {
+ pkt_size = (priv->rx_desc[entry].status & 0x1fff) - 4;
+
+ dma_inv_range((unsigned long)priv->rx_buf
+ + entry * PKT_BUF_SIZE,
+ (unsigned long)priv->rx_buf
+ + entry * PKT_BUF_SIZE + pkt_size);
+
+ net_receive(edev, priv->rx_buf + entry * PKT_BUF_SIZE,
+ pkt_size);
+
+ /*
+ * the buffer is going to be reused by HW, make sure to
+ * clean out any potentially modified data
+ */
+ dma_clean_range((unsigned long)priv->rx_buf
+ + entry * PKT_BUF_SIZE,
+ (unsigned long)priv->rx_buf
+ + entry * PKT_BUF_SIZE + pkt_size);
+
+ if (entry == NUM_RX_DESC - 1)
+ priv->rx_desc[entry].status = BD_STAT_OWN |
+ BD_STAT_EOR | PKT_BUF_SIZE;
+ else
+ priv->rx_desc[entry].status =
+ BD_STAT_OWN | PKT_BUF_SIZE;
+ priv->rx_desc[entry].buf_addr =
+ virt_to_phys(priv->rx_buf +
+ entry * PKT_BUF_SIZE);
+
+ dma_flush_range((unsigned long)&priv->rx_desc[entry],
+ (unsigned long)&priv->rx_desc[entry + 1]);
+ } else {
+ dev_err(&edev->dev, "rx error\n");
+ }
+
+ priv->cur_rx++;
+
+ return pkt_size;
+
+ } else {
+ status = RTL_R8(priv, IntrStatus);
+ RTL_W8(priv, IntrStatus, status & ~(TxErr | RxErr | SYSErr));
+ udelay(100); /* wait */
+ }
+
+ return 0;
+}
+
+static int rtl8169_get_ethaddr(struct eth_device *edev, unsigned char *m)
+{
+ struct rtl8169_priv *priv = edev->priv;
+ int i;
+
+ for (i = 0; i < 6; i++) {
+ m[i] = RTL_R8(priv, MAC0 + i);
+ }
+
+ return 0;
+}
+
+static int rtl8169_set_ethaddr(struct eth_device *edev, unsigned char *mac_addr)
+{
+ struct rtl8169_priv *priv = edev->priv;
+ int i;
+
+ RTL_W8(priv, Cfg9346, Cfg9346_Unlock);
+
+ for (i = 0; i < 6; i++) {
+ RTL_W8(priv, (MAC0 + i), mac_addr[i]);
+ RTL_R8(priv, mac_addr[i]);
+ }
+
+ RTL_W8(priv, Cfg9346, Cfg9346_Lock);
+
+ return 0;
+}
+
+static void rtl8169_eth_halt(struct eth_device *edev)
+{
+ struct rtl8169_priv *priv = edev->priv;
+
+ /* Stop the chip's Tx and Rx DMA processes. */
+ RTL_W8(priv, ChipCmd, 0x00);
+
+ /* Disable interrupts by clearing the interrupt mask. */
+ RTL_W16(priv, IntrMask, 0x0000);
+ RTL_W32(priv, RxMissed, 0);
+
+ pci_clear_master(priv->pci_dev);
+}
+
+static int rtl8169_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+ struct device_d *dev = &pdev->dev;
+ struct eth_device *edev;
+ struct rtl8169_priv *priv;
+ int ret;
+
+ /* enable pci device */
+ pci_enable_device(pdev);
+
+ priv = xzalloc(sizeof(struct rtl8169_priv));
+
+ edev = &priv->edev;
+ dev->type_data = edev;
+ edev->priv = priv;
+
+ priv->pci_dev = pdev;
+
+ priv->miibus.read = rtl8169_phy_read;
+ priv->miibus.write = rtl8169_phy_write;
+ priv->miibus.priv = priv;
+ priv->miibus.parent = &edev->dev;
+
+ priv->base = pci_iomap(pdev, pdev->device == 0x8168 ? 2 : 1);
+
+ dev_dbg(dev, "rtl%04x (rev %02x) (base=%p)\n",
+ pdev->device, pdev->revision, priv->base);
+
+ edev->init = rtl8169_init_dev;
+ edev->open = rtl8169_eth_open;
+ edev->send = rtl8169_eth_send;
+ edev->recv = rtl8169_eth_rx;
+ edev->get_ethaddr = rtl8169_get_ethaddr;
+ edev->set_ethaddr = rtl8169_set_ethaddr;
+ edev->halt = rtl8169_eth_halt;
+ edev->parent = dev;
+ ret = eth_register(edev);
+ if (ret)
+ goto eth_err;
+
+ ret = mdiobus_register(&priv->miibus);
+ if (ret)
+ goto mdio_err;
+
+ return 0;
+
+mdio_err:
+ eth_unregister(edev);
+
+eth_err:
+ free(priv);
+
+ return ret;
+}
+static DEFINE_PCI_DEVICE_TABLE(rtl8169_pci_tbl) = {
+ { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8167), },
+ { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8168), },
+ { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8169), },
+ { /* sentinel */ }
+};
+
+static struct pci_driver rtl8169_eth_driver = {
+ .name = "rtl8169_eth",
+ .id_table = rtl8169_pci_tbl,
+ .probe = rtl8169_probe,
+};
+
+static int rtl8169_init(void)
+{
+ return pci_register_driver(&rtl8169_eth_driver);
+}
+device_initcall(rtl8169_init);
diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index 97a1d933ec..97378ab59f 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -30,6 +30,7 @@ config OF_GPIO
config OF_PCI
bool
depends on PCI
+ select OF_ADDRESS_PCI
help
OpenFirmware PCI bus accessors
diff --git a/drivers/of/address.c b/drivers/of/address.c
index b3cbb15453..8018d78bcb 100644
--- a/drivers/of/address.c
+++ b/drivers/of/address.c
@@ -179,6 +179,74 @@ static int of_bus_pci_translate(__be32 *addr, u64 offset, int na)
}
#endif /* CONFIG_OF_ADDRESS_PCI */
+#ifdef CONFIG_OF_PCI
+int of_pci_range_parser_init(struct of_pci_range_parser *parser,
+ struct device_node *node)
+{
+ const int na = 3, ns = 2;
+ int rlen;
+
+ parser->node = node;
+ parser->pna = of_n_addr_cells(node);
+ parser->np = parser->pna + na + ns;
+
+ parser->range = of_get_property(node, "ranges", &rlen);
+ if (parser->range == NULL)
+ return -ENOENT;
+
+ parser->end = parser->range + rlen / sizeof(__be32);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(of_pci_range_parser_init);
+
+struct of_pci_range *of_pci_range_parser_one(struct of_pci_range_parser *parser,
+ struct of_pci_range *range)
+{
+ const int na = 3, ns = 2;
+
+ if (!range)
+ return NULL;
+
+ if (!parser->range || parser->range + parser->np > parser->end)
+ return NULL;
+
+ range->pci_space = parser->range[0];
+ range->flags = of_bus_pci_get_flags(parser->range);
+ range->pci_addr = of_read_number(parser->range + 1, ns);
+ range->cpu_addr = of_translate_address(parser->node,
+ parser->range + na);
+ range->size = of_read_number(parser->range + parser->pna + na, ns);
+
+ parser->range += parser->np;
+
+ /* Now consume following elements while they are contiguous */
+ while (parser->range + parser->np <= parser->end) {
+ u32 flags, pci_space;
+ u64 pci_addr, cpu_addr, size;
+
+ pci_space = be32_to_cpup(parser->range);
+ flags = of_bus_pci_get_flags(parser->range);
+ pci_addr = of_read_number(parser->range + 1, ns);
+ cpu_addr = of_translate_address(parser->node,
+ parser->range + na);
+ size = of_read_number(parser->range + parser->pna + na, ns);
+
+ if (flags != range->flags)
+ break;
+ if (pci_addr != range->pci_addr + range->size ||
+ cpu_addr != range->cpu_addr + range->size)
+ break;
+
+ range->size += size;
+ parser->range += parser->np;
+ }
+
+ return range;
+}
+EXPORT_SYMBOL_GPL(of_pci_range_parser_one);
+#endif /* CONFIG_OF_PCI */
+
/*
* Array of bus specific translators
*/
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index d17a151082..0e9308e97b 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -30,6 +30,13 @@ config PCI_MVEBU
select OF_PCI
select PCI
+config PCI_TEGRA
+ bool "NVDIA Tegra PCIe driver"
+ depends on ARCH_TEGRA
+ select OF_ADDRESS_PCI
+ select OF_PCI
+ select PCI
+
endmenu
endif
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index 442353173c..b93b28abea 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -8,3 +8,4 @@ ccflags-$(CONFIG_PCI_DEBUG) := -DDEBUG
CPPFLAGS += $(ccflags-y)
obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o pci-mvebu-phy.o
+obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index 8215ee5638..866ab08067 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -86,7 +86,8 @@ int pci_register_device(struct pci_dev *pdev)
struct device_d *dev = &pdev->dev;
int ret;
- strcpy(dev->name, "pci");
+ snprintf(dev->name, MAX_DRIVER_NAME, "pci-%04x:%04x.",
+ pdev->vendor, pdev->device);
dev->bus = &pci_bus;
dev->id = DEVICE_ID_DYNAMIC;
diff --git a/drivers/pci/pci-tegra.c b/drivers/pci/pci-tegra.c
new file mode 100644
index 0000000000..f2ade7749d
--- /dev/null
+++ b/drivers/pci/pci-tegra.c
@@ -0,0 +1,1305 @@
+/*
+ * Copyright (C) 2014 Lucas Stach <l.stach@pengutronix.de>
+ *
+ * based on code
+ * Copyright (c) 2010, CompuLab, Ltd.
+ * Copyright (c) 2008-2009, 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 <clock.h>
+#include <malloc.h>
+#include <io.h>
+#include <init.h>
+#include <asm/mmu.h>
+
+#include <linux/clk.h>
+#include <linux/kernel.h>
+#include <of_address.h>
+#include <of_pci.h>
+#include <linux/pci.h>
+#include <linux/phy/phy.h>
+#include <linux/reset.h>
+#include <sizes.h>
+#include <mach/tegra-powergate.h>
+#include <regulator.h>
+
+/* register definitions */
+
+#define AFI_AXI_BAR0_SZ 0x00
+#define AFI_AXI_BAR1_SZ 0x04
+#define AFI_AXI_BAR2_SZ 0x08
+#define AFI_AXI_BAR3_SZ 0x0c
+#define AFI_AXI_BAR4_SZ 0x10
+#define AFI_AXI_BAR5_SZ 0x14
+
+#define AFI_AXI_BAR0_START 0x18
+#define AFI_AXI_BAR1_START 0x1c
+#define AFI_AXI_BAR2_START 0x20
+#define AFI_AXI_BAR3_START 0x24
+#define AFI_AXI_BAR4_START 0x28
+#define AFI_AXI_BAR5_START 0x2c
+
+#define AFI_FPCI_BAR0 0x30
+#define AFI_FPCI_BAR1 0x34
+#define AFI_FPCI_BAR2 0x38
+#define AFI_FPCI_BAR3 0x3c
+#define AFI_FPCI_BAR4 0x40
+#define AFI_FPCI_BAR5 0x44
+
+#define AFI_CACHE_BAR0_SZ 0x48
+#define AFI_CACHE_BAR0_ST 0x4c
+#define AFI_CACHE_BAR1_SZ 0x50
+#define AFI_CACHE_BAR1_ST 0x54
+
+#define AFI_MSI_BAR_SZ 0x60
+#define AFI_MSI_FPCI_BAR_ST 0x64
+#define AFI_MSI_AXI_BAR_ST 0x68
+
+#define AFI_MSI_VEC0 0x6c
+#define AFI_MSI_VEC1 0x70
+#define AFI_MSI_VEC2 0x74
+#define AFI_MSI_VEC3 0x78
+#define AFI_MSI_VEC4 0x7c
+#define AFI_MSI_VEC5 0x80
+#define AFI_MSI_VEC6 0x84
+#define AFI_MSI_VEC7 0x88
+
+#define AFI_MSI_EN_VEC0 0x8c
+#define AFI_MSI_EN_VEC1 0x90
+#define AFI_MSI_EN_VEC2 0x94
+#define AFI_MSI_EN_VEC3 0x98
+#define AFI_MSI_EN_VEC4 0x9c
+#define AFI_MSI_EN_VEC5 0xa0
+#define AFI_MSI_EN_VEC6 0xa4
+#define AFI_MSI_EN_VEC7 0xa8
+
+#define AFI_CONFIGURATION 0xac
+#define AFI_CONFIGURATION_EN_FPCI (1 << 0)
+
+#define AFI_FPCI_ERROR_MASKS 0xb0
+
+#define AFI_INTR_MASK 0xb4
+#define AFI_INTR_MASK_INT_MASK (1 << 0)
+#define AFI_INTR_MASK_MSI_MASK (1 << 8)
+
+#define AFI_INTR_CODE 0xb8
+#define AFI_INTR_CODE_MASK 0xf
+#define AFI_INTR_AXI_SLAVE_ERROR 1
+#define AFI_INTR_AXI_DECODE_ERROR 2
+#define AFI_INTR_TARGET_ABORT 3
+#define AFI_INTR_MASTER_ABORT 4
+#define AFI_INTR_INVALID_WRITE 5
+#define AFI_INTR_LEGACY 6
+#define AFI_INTR_FPCI_DECODE_ERROR 7
+
+#define AFI_INTR_SIGNATURE 0xbc
+#define AFI_UPPER_FPCI_ADDRESS 0xc0
+#define AFI_SM_INTR_ENABLE 0xc4
+#define AFI_SM_INTR_INTA_ASSERT (1 << 0)
+#define AFI_SM_INTR_INTB_ASSERT (1 << 1)
+#define AFI_SM_INTR_INTC_ASSERT (1 << 2)
+#define AFI_SM_INTR_INTD_ASSERT (1 << 3)
+#define AFI_SM_INTR_INTA_DEASSERT (1 << 4)
+#define AFI_SM_INTR_INTB_DEASSERT (1 << 5)
+#define AFI_SM_INTR_INTC_DEASSERT (1 << 6)
+#define AFI_SM_INTR_INTD_DEASSERT (1 << 7)
+
+#define AFI_AFI_INTR_ENABLE 0xc8
+#define AFI_INTR_EN_INI_SLVERR (1 << 0)
+#define AFI_INTR_EN_INI_DECERR (1 << 1)
+#define AFI_INTR_EN_TGT_SLVERR (1 << 2)
+#define AFI_INTR_EN_TGT_DECERR (1 << 3)
+#define AFI_INTR_EN_TGT_WRERR (1 << 4)
+#define AFI_INTR_EN_DFPCI_DECERR (1 << 5)
+#define AFI_INTR_EN_AXI_DECERR (1 << 6)
+#define AFI_INTR_EN_FPCI_TIMEOUT (1 << 7)
+#define AFI_INTR_EN_PRSNT_SENSE (1 << 8)
+
+#define AFI_PCIE_CONFIG 0x0f8
+#define AFI_PCIE_CONFIG_PCIE_DISABLE(x) (1 << ((x) + 1))
+#define AFI_PCIE_CONFIG_PCIE_DISABLE_ALL 0xe
+#define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_MASK (0xf << 20)
+#define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_SINGLE (0x0 << 20)
+#define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_420 (0x0 << 20)
+#define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_X2_X1 (0x0 << 20)
+#define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_DUAL (0x1 << 20)
+#define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_222 (0x1 << 20)
+#define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_X4_X1 (0x1 << 20)
+#define AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_411 (0x2 << 20)
+
+#define AFI_FUSE 0x104
+#define AFI_FUSE_PCIE_T0_GEN2_DIS (1 << 2)
+
+#define AFI_PEX0_CTRL 0x110
+#define AFI_PEX1_CTRL 0x118
+#define AFI_PEX2_CTRL 0x128
+#define AFI_PEX_CTRL_RST (1 << 0)
+#define AFI_PEX_CTRL_CLKREQ_EN (1 << 1)
+#define AFI_PEX_CTRL_REFCLK_EN (1 << 3)
+#define AFI_PEX_CTRL_OVERRIDE_EN (1 << 4)
+
+#define AFI_PLLE_CONTROL 0x160
+#define AFI_PLLE_CONTROL_BYPASS_PADS2PLLE_CONTROL (1 << 9)
+#define AFI_PLLE_CONTROL_PADS2PLLE_CONTROL_EN (1 << 1)
+
+#define AFI_PEXBIAS_CTRL_0 0x168
+
+#define RP_VEND_XP 0x00000F00
+#define RP_VEND_XP_DL_UP (1 << 30)
+
+#define RP_PRIV_MISC 0x00000FE0
+#define RP_PRIV_MISC_PRSNT_MAP_EP_PRSNT (0xE << 0)
+#define RP_PRIV_MISC_PRSNT_MAP_EP_ABSNT (0xF << 0)
+
+#define RP_LINK_CONTROL_STATUS 0x00000090
+#define RP_LINK_CONTROL_STATUS_DL_LINK_ACTIVE 0x20000000
+#define RP_LINK_CONTROL_STATUS_LINKSTAT_MASK 0x3fff0000
+
+#define PADS_CTL_SEL 0x0000009C
+
+#define PADS_CTL 0x000000A0
+#define PADS_CTL_IDDQ_1L (1 << 0)
+#define PADS_CTL_TX_DATA_EN_1L (1 << 6)
+#define PADS_CTL_RX_DATA_EN_1L (1 << 10)
+
+#define PADS_PLL_CTL_TEGRA20 0x000000B8
+#define PADS_PLL_CTL_TEGRA30 0x000000B4
+#define PADS_PLL_CTL_RST_B4SM (1 << 1)
+#define PADS_PLL_CTL_LOCKDET (1 << 8)
+#define PADS_PLL_CTL_REFCLK_MASK (0x3 << 16)
+#define PADS_PLL_CTL_REFCLK_INTERNAL_CML (0 << 16)
+#define PADS_PLL_CTL_REFCLK_INTERNAL_CMOS (1 << 16)
+#define PADS_PLL_CTL_REFCLK_EXTERNAL (2 << 16)
+#define PADS_PLL_CTL_TXCLKREF_MASK (0x1 << 20)
+#define PADS_PLL_CTL_TXCLKREF_DIV10 (0 << 20)
+#define PADS_PLL_CTL_TXCLKREF_DIV5 (1 << 20)
+#define PADS_PLL_CTL_TXCLKREF_BUF_EN (1 << 22)
+
+#define PADS_REFCLK_CFG0 0x000000C8
+#define PADS_REFCLK_CFG1 0x000000CC
+
+/*
+ * Fields in PADS_REFCLK_CFG*. Those registers form an array of 16-bit
+ * entries, one entry per PCIe port. These field definitions and desired
+ * values aren't in the TRM, but do come from NVIDIA.
+ */
+#define PADS_REFCLK_CFG_TERM_SHIFT 2 /* 6:2 */
+#define PADS_REFCLK_CFG_E_TERM_SHIFT 7
+#define PADS_REFCLK_CFG_PREDI_SHIFT 8 /* 11:8 */
+#define PADS_REFCLK_CFG_DRVI_SHIFT 12 /* 15:12 */
+
+/* Default value provided by HW engineering is 0xfa5c */
+#define PADS_REFCLK_CFG_VALUE \
+ ( \
+ (0x17 << PADS_REFCLK_CFG_TERM_SHIFT) | \
+ (0 << PADS_REFCLK_CFG_E_TERM_SHIFT) | \
+ (0xa << PADS_REFCLK_CFG_PREDI_SHIFT) | \
+ (0xf << PADS_REFCLK_CFG_DRVI_SHIFT) \
+ )
+
+/* used to differentiate between Tegra SoC generations */
+struct tegra_pcie_soc_data {
+ unsigned int num_ports;
+ unsigned int msi_base_shift;
+ u32 pads_pll_ctl;
+ u32 tx_ref_sel;
+ bool has_pex_clkreq_en;
+ bool has_pex_bias_ctrl;
+ bool has_intr_prsnt_sense;
+ bool has_avdd_supply;
+ bool has_cml_clk;
+ bool has_gen2;
+};
+
+struct tegra_pcie {
+ struct device_d *dev;
+ struct pci_controller pci;
+
+ void __iomem *pads;
+ void __iomem *afi;
+ void __iomem *cs;
+
+ struct list_head buses;
+
+ struct resource io;
+ struct resource mem;
+ struct resource prefetch;
+ struct resource busn;
+ struct resource *cs_res;
+
+ struct clk *pex_clk;
+ struct clk *afi_clk;
+ struct clk *pll_e;
+ struct clk *cml_clk;
+
+ struct reset_control *pex_rst;
+ struct reset_control *afi_rst;
+ struct reset_control *pcie_xrst;
+
+ struct phy *phy;
+
+ struct list_head ports;
+ unsigned int num_ports;
+ u32 xbar_config;
+
+ struct regulator *pex_clk_supply;
+ struct regulator *vdd_supply;
+ struct regulator *avdd_supply;
+
+ const struct tegra_pcie_soc_data *soc_data;
+};
+
+struct tegra_pcie_port {
+ struct tegra_pcie *pcie;
+ struct list_head list;
+ struct resource regs;
+ void __iomem *base;
+ unsigned int index;
+ unsigned int lanes;
+};
+
+static inline struct tegra_pcie *host_to_pcie(struct pci_controller *host)
+{
+ return container_of(host, struct tegra_pcie, pci);
+}
+
+static inline void afi_writel(struct tegra_pcie *pcie, u32 value,
+ unsigned long offset)
+{
+ writel(value, pcie->afi + offset);
+}
+
+static inline u32 afi_readl(struct tegra_pcie *pcie, unsigned long offset)
+{
+ return readl(pcie->afi + offset);
+}
+
+static inline void pads_writel(struct tegra_pcie *pcie, u32 value,
+ unsigned long offset)
+{
+ writel(value, pcie->pads + offset);
+}
+
+static inline u32 pads_readl(struct tegra_pcie *pcie, unsigned long offset)
+{
+ return readl(pcie->pads + offset);
+}
+
+static void __iomem *tegra_pcie_conf_address(struct pci_bus *bus,
+ unsigned int devfn,
+ int where)
+{
+ struct tegra_pcie *pcie = host_to_pcie(bus->host);
+ void __iomem *addr = NULL;
+
+ if (bus->number == 0) {
+ unsigned int slot = PCI_SLOT(devfn);
+ struct tegra_pcie_port *port;
+
+ list_for_each_entry(port, &pcie->ports, list) {
+ if (port->index + 1 == slot) {
+ addr = (void __force __iomem *)
+ port->regs.start + (where & ~3);
+ break;
+ }
+ }
+ } else {
+ addr = pcie->cs;
+
+ addr += ((where & 0xf00) << 16) | (bus->number << 16) |
+ (PCI_SLOT(devfn) << 11) | (PCI_FUNC(devfn) << 8) |
+ (where & 0xfc);
+ }
+
+ return addr;
+}
+
+static int tegra_pcie_read_conf(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 *value)
+{
+ void __iomem *addr;
+
+ addr = tegra_pcie_conf_address(bus, devfn, where);
+ if (!addr) {
+ *value = 0xffffffff;
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ }
+
+ *value = readl(addr);
+
+ if (size == 1)
+ *value = (*value >> (8 * (where & 3))) & 0xff;
+ else if (size == 2)
+ *value = (*value >> (8 * (where & 3))) & 0xffff;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int tegra_pcie_write_conf(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 value)
+{
+ void __iomem *addr;
+ u32 mask, tmp;
+
+ addr = tegra_pcie_conf_address(bus, devfn, where);
+ if (!addr)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ if (size == 4) {
+ writel(value, addr);
+ return PCIBIOS_SUCCESSFUL;
+ }
+
+ if (size == 2)
+ mask = ~(0xffff << ((where & 0x3) * 8));
+ else if (size == 1)
+ mask = ~(0xff << ((where & 0x3) * 8));
+ else
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ tmp = readl(addr) & mask;
+ tmp |= value << ((where & 0x3) * 8);
+ writel(tmp, addr);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int tegra_pcie_res_start(struct pci_bus *bus, resource_size_t res_addr)
+{
+ return res_addr;
+}
+
+static struct pci_ops tegra_pcie_ops = {
+ .read = tegra_pcie_read_conf,
+ .write = tegra_pcie_write_conf,
+ .res_start = tegra_pcie_res_start,
+};
+
+static unsigned long tegra_pcie_port_get_pex_ctrl(struct tegra_pcie_port *port)
+{
+ unsigned long ret = 0;
+
+ switch (port->index) {
+ case 0:
+ ret = AFI_PEX0_CTRL;
+ break;
+
+ case 1:
+ ret = AFI_PEX1_CTRL;
+ break;
+
+ case 2:
+ ret = AFI_PEX2_CTRL;
+ break;
+ }
+
+ return ret;
+}
+
+static void tegra_pcie_port_reset(struct tegra_pcie_port *port)
+{
+ unsigned long ctrl = tegra_pcie_port_get_pex_ctrl(port);
+ unsigned long value;
+
+ /* pulse reset signal */
+ value = afi_readl(port->pcie, ctrl);
+ value &= ~AFI_PEX_CTRL_RST;
+ afi_writel(port->pcie, value, ctrl);
+
+ mdelay(1);
+
+ value = afi_readl(port->pcie, ctrl);
+ value |= AFI_PEX_CTRL_RST;
+ afi_writel(port->pcie, value, ctrl);
+}
+
+static void tegra_pcie_port_enable(struct tegra_pcie_port *port)
+{
+ const struct tegra_pcie_soc_data *soc = port->pcie->soc_data;
+ unsigned long ctrl = tegra_pcie_port_get_pex_ctrl(port);
+ unsigned long value;
+
+ /* enable reference clock */
+ value = afi_readl(port->pcie, ctrl);
+ value |= AFI_PEX_CTRL_REFCLK_EN;
+
+ if (soc->has_pex_clkreq_en)
+ value |= AFI_PEX_CTRL_CLKREQ_EN;
+
+ value |= AFI_PEX_CTRL_OVERRIDE_EN;
+
+ afi_writel(port->pcie, value, ctrl);
+
+ tegra_pcie_port_reset(port);
+}
+
+static void tegra_pcie_port_disable(struct tegra_pcie_port *port)
+{
+ unsigned long ctrl = tegra_pcie_port_get_pex_ctrl(port);
+ unsigned long value;
+
+ /* assert port reset */
+ value = afi_readl(port->pcie, ctrl);
+ value &= ~AFI_PEX_CTRL_RST;
+ afi_writel(port->pcie, value, ctrl);
+
+ /* disable reference clock */
+ value = afi_readl(port->pcie, ctrl);
+ value &= ~AFI_PEX_CTRL_REFCLK_EN;
+ afi_writel(port->pcie, value, ctrl);
+}
+
+static void tegra_pcie_port_free(struct tegra_pcie_port *port)
+{
+ list_del(&port->list);
+ kfree(port);
+}
+
+#if 0
+static void tegra_pcie_fixup_bridge(struct pci_dev *dev)
+{
+ u16 reg;
+
+ if ((dev->class >> 16) == PCI_BASE_CLASS_BRIDGE) {
+ pci_read_config_word(dev, PCI_COMMAND, &reg);
+ reg |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
+ PCI_COMMAND_MASTER | PCI_COMMAND_SERR);
+ pci_write_config_word(dev, PCI_COMMAND, reg);
+ }
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, tegra_pcie_fixup_bridge);
+
+/* Tegra PCIE root complex wrongly reports device class */
+static void tegra_pcie_fixup_class(struct pci_dev *dev)
+{
+ dev->class = PCI_CLASS_BRIDGE_PCI << 8;
+}
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA, 0x0bf0, tegra_pcie_fixup_class);
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA, 0x0bf1, tegra_pcie_fixup_class);
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA, 0x0e1c, tegra_pcie_fixup_class);
+DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_NVIDIA, 0x0e1d, tegra_pcie_fixup_class);
+
+/* Tegra PCIE requires relaxed ordering */
+static void tegra_pcie_relax_enable(struct pci_dev *dev)
+{
+ pcie_capability_set_word(dev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_RELAX_EN);
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, tegra_pcie_relax_enable);
+#endif
+
+/*
+ * FPCI map is as follows:
+ * - 0xfdfc000000: I/O space
+ * - 0xfdfe000000: type 0 configuration space
+ * - 0xfdff000000: type 1 configuration space
+ * - 0xfe00000000: type 0 extended configuration space
+ * - 0xfe10000000: type 1 extended configuration space
+ */
+static void tegra_pcie_setup_translations(struct tegra_pcie *pcie)
+{
+ u32 fpci_bar, size, axi_address;
+
+ /* Bar 0: type 1 extended configuration space */
+ fpci_bar = 0xfe100000;
+ size = resource_size(pcie->cs_res);
+ axi_address = pcie->cs_res->start;
+ afi_writel(pcie, axi_address, AFI_AXI_BAR0_START);
+ afi_writel(pcie, size >> 12, AFI_AXI_BAR0_SZ);
+ afi_writel(pcie, fpci_bar, AFI_FPCI_BAR0);
+
+ /* Bar 1: downstream IO bar */
+ fpci_bar = 0xfdfc0000;
+ size = resource_size(&pcie->io);
+ axi_address = pcie->io.start;
+ afi_writel(pcie, axi_address, AFI_AXI_BAR1_START);
+ afi_writel(pcie, size >> 12, AFI_AXI_BAR1_SZ);
+ afi_writel(pcie, fpci_bar, AFI_FPCI_BAR1);
+
+ /* Bar 2: prefetchable memory BAR */
+ fpci_bar = (((pcie->prefetch.start >> 12) & 0x0fffffff) << 4) | 0x1;
+ size = resource_size(&pcie->prefetch);
+ axi_address = pcie->prefetch.start;
+ afi_writel(pcie, axi_address, AFI_AXI_BAR2_START);
+ afi_writel(pcie, size >> 12, AFI_AXI_BAR2_SZ);
+ afi_writel(pcie, fpci_bar, AFI_FPCI_BAR2);
+
+ /* Bar 3: non prefetchable memory BAR */
+ fpci_bar = (((pcie->mem.start >> 12) & 0x0fffffff) << 4) | 0x1;
+ size = resource_size(&pcie->mem);
+ axi_address = pcie->mem.start;
+ afi_writel(pcie, axi_address, AFI_AXI_BAR3_START);
+ afi_writel(pcie, size >> 12, AFI_AXI_BAR3_SZ);
+ afi_writel(pcie, fpci_bar, AFI_FPCI_BAR3);
+
+ /* NULL out the remaining BARs as they are not used */
+ afi_writel(pcie, 0, AFI_AXI_BAR4_START);
+ afi_writel(pcie, 0, AFI_AXI_BAR4_SZ);
+ afi_writel(pcie, 0, AFI_FPCI_BAR4);
+
+ afi_writel(pcie, 0, AFI_AXI_BAR5_START);
+ afi_writel(pcie, 0, AFI_AXI_BAR5_SZ);
+ afi_writel(pcie, 0, AFI_FPCI_BAR5);
+
+ /* map all upstream transactions as uncached */
+ /* FIXME: is 0 ok for BAR0 start ??? */
+ afi_writel(pcie, 0, AFI_CACHE_BAR0_ST);
+ afi_writel(pcie, 0, AFI_CACHE_BAR0_SZ);
+ afi_writel(pcie, 0, AFI_CACHE_BAR1_ST);
+ afi_writel(pcie, 0, AFI_CACHE_BAR1_SZ);
+
+ /* MSI translations are setup only when needed */
+ afi_writel(pcie, 0, AFI_MSI_FPCI_BAR_ST);
+ afi_writel(pcie, 0, AFI_MSI_BAR_SZ);
+ afi_writel(pcie, 0, AFI_MSI_AXI_BAR_ST);
+ afi_writel(pcie, 0, AFI_MSI_BAR_SZ);
+}
+
+static int tegra_pcie_phy_enable(struct tegra_pcie *pcie)
+{
+ const struct tegra_pcie_soc_data *soc = pcie->soc_data;
+ u32 value;
+
+ /* initialize internal PHY, enable up to 16 PCIE lanes */
+ pads_writel(pcie, 0x0, PADS_CTL_SEL);
+
+ /* override IDDQ to 1 on all 4 lanes */
+ value = pads_readl(pcie, PADS_CTL);
+ value |= PADS_CTL_IDDQ_1L;
+ pads_writel(pcie, value, PADS_CTL);
+
+ /*
+ * Set up PHY PLL inputs select PLLE output as refclock,
+ * set TX ref sel to div10 (not div5).
+ */
+ value = pads_readl(pcie, soc->pads_pll_ctl);
+ value &= ~(PADS_PLL_CTL_REFCLK_MASK | PADS_PLL_CTL_TXCLKREF_MASK);
+ value |= PADS_PLL_CTL_REFCLK_INTERNAL_CML | soc->tx_ref_sel;
+ pads_writel(pcie, value, soc->pads_pll_ctl);
+
+ /* reset PLL */
+ value = pads_readl(pcie, soc->pads_pll_ctl);
+ value &= ~PADS_PLL_CTL_RST_B4SM;
+ pads_writel(pcie, value, soc->pads_pll_ctl);
+
+ udelay(20);
+
+ /* take PLL out of reset */
+ value = pads_readl(pcie, soc->pads_pll_ctl);
+ value |= PADS_PLL_CTL_RST_B4SM;
+ pads_writel(pcie, value, soc->pads_pll_ctl);
+
+ /* Configure the reference clock driver */
+ value = PADS_REFCLK_CFG_VALUE | (PADS_REFCLK_CFG_VALUE << 16);
+ pads_writel(pcie, value, PADS_REFCLK_CFG0);
+ if (soc->num_ports > 2)
+ pads_writel(pcie, PADS_REFCLK_CFG_VALUE, PADS_REFCLK_CFG1);
+
+ /* wait for the PLL to lock */
+ if (wait_on_timeout(300 * MSECOND,
+ (pads_readl(pcie, soc->pads_pll_ctl) & PADS_PLL_CTL_LOCKDET))) {
+ pr_err("Tegra PCIe error: timeout waiting for PLL\n");
+ return -EBUSY;
+ }
+
+ /* turn off IDDQ override */
+ value = pads_readl(pcie, PADS_CTL);
+ value &= ~PADS_CTL_IDDQ_1L;
+ pads_writel(pcie, value, PADS_CTL);
+
+ /* enable TX/RX data */
+ value = pads_readl(pcie, PADS_CTL);
+ value |= PADS_CTL_TX_DATA_EN_1L | PADS_CTL_RX_DATA_EN_1L;
+ pads_writel(pcie, value, PADS_CTL);
+
+ return 0;
+}
+
+static int tegra_pcie_enable_controller(struct tegra_pcie *pcie)
+{
+ const struct tegra_pcie_soc_data *soc = pcie->soc_data;
+ struct tegra_pcie_port *port;
+ unsigned long value;
+ int err;
+
+ /* enable PLL power down */
+ if (pcie->phy) {
+ value = afi_readl(pcie, AFI_PLLE_CONTROL);
+ value &= ~AFI_PLLE_CONTROL_BYPASS_PADS2PLLE_CONTROL;
+ value |= AFI_PLLE_CONTROL_PADS2PLLE_CONTROL_EN;
+ afi_writel(pcie, value, AFI_PLLE_CONTROL);
+ }
+
+ /* power down PCIe slot clock bias pad */
+ if (soc->has_pex_bias_ctrl)
+ afi_writel(pcie, 0, AFI_PEXBIAS_CTRL_0);
+
+ /* configure mode and disable all ports */
+ value = afi_readl(pcie, AFI_PCIE_CONFIG);
+ value &= ~AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_MASK;
+ value |= AFI_PCIE_CONFIG_PCIE_DISABLE_ALL | pcie->xbar_config;
+
+ list_for_each_entry(port, &pcie->ports, list)
+ value &= ~AFI_PCIE_CONFIG_PCIE_DISABLE(port->index);
+
+ afi_writel(pcie, value, AFI_PCIE_CONFIG);
+
+ if (soc->has_gen2) {
+ value = afi_readl(pcie, AFI_FUSE);
+ value &= ~AFI_FUSE_PCIE_T0_GEN2_DIS;
+ afi_writel(pcie, value, AFI_FUSE);
+ } else {
+ value = afi_readl(pcie, AFI_FUSE);
+ value |= AFI_FUSE_PCIE_T0_GEN2_DIS;
+ afi_writel(pcie, value, AFI_FUSE);
+ }
+
+ if (!pcie->phy)
+ err = tegra_pcie_phy_enable(pcie);
+ else
+ err = phy_power_on(pcie->phy);
+
+ /* take the PCIe interface module out of reset */
+ reset_control_deassert(pcie->pcie_xrst);
+
+ /* finally enable PCIe */
+ value = afi_readl(pcie, AFI_CONFIGURATION);
+ value |= AFI_CONFIGURATION_EN_FPCI;
+ afi_writel(pcie, value, AFI_CONFIGURATION);
+
+ value = AFI_INTR_EN_INI_SLVERR | AFI_INTR_EN_INI_DECERR |
+ AFI_INTR_EN_TGT_SLVERR | AFI_INTR_EN_TGT_DECERR |
+ AFI_INTR_EN_TGT_WRERR | AFI_INTR_EN_DFPCI_DECERR;
+
+ if (soc->has_intr_prsnt_sense)
+ value |= AFI_INTR_EN_PRSNT_SENSE;
+
+ afi_writel(pcie, value, AFI_AFI_INTR_ENABLE);
+ afi_writel(pcie, 0xffffffff, AFI_SM_INTR_ENABLE);
+
+ /* don't enable MSI for now, only when needed */
+ afi_writel(pcie, AFI_INTR_MASK_INT_MASK, AFI_INTR_MASK);
+
+ /* disable all exceptions */
+ afi_writel(pcie, 0, AFI_FPCI_ERROR_MASKS);
+
+ return 0;
+}
+
+static void tegra_pcie_power_off(struct tegra_pcie *pcie)
+{
+ const struct tegra_pcie_soc_data *soc = pcie->soc_data;
+ int err;
+
+ /* TODO: disable and unprepare clocks? */
+
+ err = phy_power_off(pcie->phy);
+ if (err < 0)
+ dev_warn(pcie->dev, "failed to power off PHY: %d\n", err);
+
+ reset_control_assert(pcie->pcie_xrst);
+ reset_control_assert(pcie->afi_rst);
+ reset_control_assert(pcie->pex_rst);
+
+ tegra_powergate_power_off(TEGRA_POWERGATE_PCIE);
+
+ if (soc->has_avdd_supply) {
+ err = regulator_disable(pcie->avdd_supply);
+ if (err < 0)
+ dev_warn(pcie->dev,
+ "failed to disable AVDD regulator: %d\n",
+ err);
+ }
+
+ err = regulator_disable(pcie->pex_clk_supply);
+ if (err < 0)
+ dev_warn(pcie->dev, "failed to disable pex-clk regulator: %d\n",
+ err);
+
+ err = regulator_disable(pcie->vdd_supply);
+ if (err < 0)
+ dev_warn(pcie->dev, "failed to disable VDD regulator: %d\n",
+ err);
+}
+
+static int tegra_pcie_power_on(struct tegra_pcie *pcie)
+{
+ const struct tegra_pcie_soc_data *soc = pcie->soc_data;
+ int err;
+
+ reset_control_assert(pcie->pcie_xrst);
+ reset_control_assert(pcie->afi_rst);
+ reset_control_assert(pcie->pex_rst);
+
+ tegra_powergate_power_off(TEGRA_POWERGATE_PCIE);
+
+ /* enable regulators */
+ err = regulator_enable(pcie->vdd_supply);
+ if (err < 0) {
+ dev_err(pcie->dev, "failed to enable VDD regulator: %d\n", err);
+ return err;
+ }
+
+ err = regulator_enable(pcie->pex_clk_supply);
+ if (err < 0) {
+ dev_err(pcie->dev, "failed to enable pex-clk regulator: %d\n",
+ err);
+ return err;
+ }
+
+ if (soc->has_avdd_supply) {
+ err = regulator_enable(pcie->avdd_supply);
+ if (err < 0) {
+ dev_err(pcie->dev,
+ "failed to enable AVDD regulator: %d\n",
+ err);
+ return err;
+ }
+ }
+
+ err = tegra_powergate_sequence_power_up(TEGRA_POWERGATE_PCIE,
+ pcie->pex_clk,
+ pcie->pex_rst);
+ if (err) {
+ dev_err(pcie->dev, "powerup sequence failed: %d\n", err);
+ return err;
+ }
+
+ reset_control_deassert(pcie->afi_rst);
+
+ err = clk_enable(pcie->afi_clk);
+ if (err < 0) {
+ dev_err(pcie->dev, "failed to enable AFI clock: %d\n", err);
+ return err;
+ }
+
+ if (soc->has_cml_clk) {
+ err = clk_enable(pcie->cml_clk);
+ if (err < 0) {
+ dev_err(pcie->dev, "failed to enable CML clock: %d\n",
+ err);
+ return err;
+ }
+ }
+
+ err = clk_enable(pcie->pll_e);
+ if (err < 0) {
+ dev_err(pcie->dev, "failed to enable PLLE clock: %d\n", err);
+ return err;
+ }
+
+ return 0;
+}
+
+static int tegra_pcie_clocks_get(struct tegra_pcie *pcie)
+{
+ const struct tegra_pcie_soc_data *soc = pcie->soc_data;
+
+ pcie->pex_clk = clk_get(pcie->dev, "pex");
+ if (IS_ERR(pcie->pex_clk))
+ return PTR_ERR(pcie->pex_clk);
+
+ pcie->afi_clk = clk_get(pcie->dev, "afi");
+ if (IS_ERR(pcie->afi_clk))
+ return PTR_ERR(pcie->afi_clk);
+
+ pcie->pll_e = clk_get(pcie->dev, "pll_e");
+ if (IS_ERR(pcie->pll_e))
+ return PTR_ERR(pcie->pll_e);
+
+ if (soc->has_cml_clk) {
+ pcie->cml_clk = clk_get(pcie->dev, "cml");
+ if (IS_ERR(pcie->cml_clk))
+ return PTR_ERR(pcie->cml_clk);
+ }
+
+ return 0;
+}
+
+static int tegra_pcie_resets_get(struct tegra_pcie *pcie)
+{
+ pcie->pex_rst = reset_control_get(pcie->dev, "pex");
+ if (IS_ERR(pcie->pex_rst))
+ return PTR_ERR(pcie->pex_rst);
+
+ pcie->afi_rst = reset_control_get(pcie->dev, "afi");
+ if (IS_ERR(pcie->afi_rst))
+ return PTR_ERR(pcie->afi_rst);
+
+ pcie->pcie_xrst = reset_control_get(pcie->dev, "pcie_x");
+ if (IS_ERR(pcie->pcie_xrst))
+ return PTR_ERR(pcie->pcie_xrst);
+
+ return 0;
+}
+
+static int tegra_pcie_get_resources(struct tegra_pcie *pcie)
+{
+ struct device_d *dev = pcie->dev;
+ int err;
+
+ err = tegra_pcie_clocks_get(pcie);
+ if (err) {
+ dev_err(dev, "failed to get clocks: %d\n", err);
+ return err;
+ }
+
+ err = tegra_pcie_resets_get(pcie);
+ if (err) {
+ dev_err(dev, "failed to get resets: %d\n", err);
+ return err;
+ }
+
+ pcie->phy = phy_optional_get(pcie->dev, "pcie");
+ if (IS_ERR(pcie->phy)) {
+ err = PTR_ERR(pcie->phy);
+ dev_err(dev, "failed to get PHY: %d\n", err);
+ return err;
+ }
+
+ err = phy_init(pcie->phy);
+ if (err < 0) {
+ dev_err(dev, "failed to initialize PHY: %d\n", err);
+ return err;
+ }
+
+ err = tegra_pcie_power_on(pcie);
+ if (err) {
+ dev_err(dev, "failed to power up: %d\n", err);
+ return err;
+ }
+
+ pcie->pads = dev_request_mem_region_by_name(dev, "pads");
+ if (IS_ERR(pcie->pads)) {
+ err = PTR_ERR(pcie->pads);
+ goto poweroff;
+ }
+
+ pcie->afi = dev_request_mem_region_by_name(dev, "afi");
+ if (IS_ERR(pcie->afi)) {
+ err = PTR_ERR(pcie->afi);
+ goto poweroff;
+ }
+
+ pcie->cs_res = dev_get_resource_by_name(dev, IORESOURCE_MEM, "cs");
+ pcie->cs = dev_request_mem_region_by_name(dev, "cs");
+ if (IS_ERR(pcie->cs)) {
+ err = PTR_ERR(pcie->cs);
+ goto poweroff;
+ }
+
+ return 0;
+
+poweroff:
+ tegra_pcie_power_off(pcie);
+ return err;
+}
+
+static int tegra_pcie_put_resources(struct tegra_pcie *pcie)
+{
+ int err;
+
+ tegra_pcie_power_off(pcie);
+
+ err = phy_exit(pcie->phy);
+ if (err < 0)
+ dev_err(pcie->dev, "failed to teardown PHY: %d\n", err);
+
+ return 0;
+}
+
+static int tegra_pcie_get_xbar_config(struct tegra_pcie *pcie, u32 lanes,
+ u32 *xbar)
+{
+ struct device_node *np = pcie->dev->device_node;
+
+ if (of_device_is_compatible(np, "nvidia,tegra124-pcie")) {
+ switch (lanes) {
+ case 0x0000104:
+ dev_info(pcie->dev, "4x1, 1x1 configuration\n");
+ *xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_X4_X1;
+ return 0;
+
+ case 0x0000102:
+ dev_info(pcie->dev, "2x1, 1x1 configuration\n");
+ *xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_X2_X1;
+ return 0;
+ }
+ } else if (of_device_is_compatible(np, "nvidia,tegra30-pcie")) {
+ switch (lanes) {
+ case 0x00000204:
+ dev_info(pcie->dev, "4x1, 2x1 configuration\n");
+ *xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_420;
+ return 0;
+
+ case 0x00020202:
+ dev_info(pcie->dev, "2x3 configuration\n");
+ *xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_222;
+ return 0;
+
+ case 0x00010104:
+ dev_info(pcie->dev, "4x1, 1x2 configuration\n");
+ *xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_411;
+ return 0;
+ }
+ } else if (of_device_is_compatible(np, "nvidia,tegra20-pcie")) {
+ switch (lanes) {
+ case 0x00000004:
+ dev_info(pcie->dev, "single-mode configuration\n");
+ *xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_SINGLE;
+ return 0;
+
+ case 0x00000202:
+ dev_info(pcie->dev, "dual-mode configuration\n");
+ *xbar = AFI_PCIE_CONFIG_SM2TMS0_XBAR_CONFIG_DUAL;
+ return 0;
+ }
+ }
+
+ return -EINVAL;
+}
+
+static int tegra_pcie_parse_dt(struct tegra_pcie *pcie)
+{
+ const struct tegra_pcie_soc_data *soc = pcie->soc_data;
+ struct device_node *np = pcie->dev->device_node, *port;
+ struct of_pci_range_parser parser;
+ struct of_pci_range range;
+ struct resource *rp_res;
+ struct resource res;
+ u32 lanes = 0;
+ int err;
+
+ if (of_pci_range_parser_init(&parser, np)) {
+ dev_err(pcie->dev, "missing \"ranges\" property\n");
+ return -EINVAL;
+ }
+
+ pcie->vdd_supply = regulator_get(pcie->dev, "vdd");
+ if (IS_ERR(pcie->vdd_supply))
+ return PTR_ERR(pcie->vdd_supply);
+
+ pcie->pex_clk_supply = regulator_get(pcie->dev, "pex-clk");
+ if (IS_ERR(pcie->pex_clk_supply))
+ return PTR_ERR(pcie->pex_clk_supply);
+
+ if (soc->has_avdd_supply) {
+ pcie->avdd_supply = regulator_get(pcie->dev, "avdd");
+ if (IS_ERR(pcie->avdd_supply))
+ return PTR_ERR(pcie->avdd_supply);
+ }
+
+ for_each_of_pci_range(&parser, &range) {
+ of_pci_range_to_resource(&range, np, &res);
+
+ switch (res.flags & IORESOURCE_TYPE_BITS) {
+ case IORESOURCE_IO:
+ memcpy(&pcie->io, &res, sizeof(res));
+ pcie->io.name = "I/O";
+ break;
+
+ case IORESOURCE_MEM:
+ if (res.flags & IORESOURCE_PREFETCH) {
+ memcpy(&pcie->prefetch, &res, sizeof(res));
+ pcie->prefetch.name = "PREFETCH";
+ } else {
+ memcpy(&pcie->mem, &res, sizeof(res));
+ pcie->mem.name = "MEM";
+ }
+ break;
+ }
+ }
+#if 0
+ err = of_pci_parse_bus_range(np, &pcie->busn);
+ if (err < 0) {
+ dev_err(pcie->dev, "failed to parse ranges property: %d\n",
+ err);
+ pcie->busn.name = np->name;
+ pcie->busn.start = 0;
+ pcie->busn.end = 0xff;
+ pcie->busn.flags = IORESOURCE_BUS;
+ }
+#endif
+ /* parse root ports */
+ for_each_child_of_node(np, port) {
+ struct tegra_pcie_port *rp;
+ unsigned int index;
+ u32 value;
+
+ err = of_pci_get_devfn(port);
+ if (err < 0) {
+ dev_err(pcie->dev, "failed to parse address: %d\n",
+ err);
+ return err;
+ }
+
+ index = PCI_SLOT(err);
+
+ if (index < 1 || index > soc->num_ports) {
+ dev_err(pcie->dev, "invalid port number: %d\n", index);
+ return -EINVAL;
+ }
+
+ index--;
+
+ err = of_property_read_u32(port, "nvidia,num-lanes", &value);
+ if (err < 0) {
+ dev_err(pcie->dev, "failed to parse # of lanes: %d\n",
+ err);
+ return err;
+ }
+
+ if (value > 16) {
+ dev_err(pcie->dev, "invalid # of lanes: %u\n", value);
+ return -EINVAL;
+ }
+
+ lanes |= value << (index << 3);
+
+ if (!of_device_is_available(port))
+ continue;
+
+ rp = kzalloc(sizeof(*rp), GFP_KERNEL);
+ if (!rp)
+ return -ENOMEM;
+
+ err = of_address_to_resource(port, 0, &rp->regs);
+ if (err < 0) {
+ dev_err(pcie->dev, "failed to parse address: %d\n",
+ err);
+ return err;
+ }
+
+ /*
+ * if the port address is inside the NULL page we alias this
+ * range at +1MB and fix up the resource, otherwise just request
+ */
+ if (!(rp->regs.start & 0xfffff000)) {
+ rp_res = request_iomem_region(dev_name(pcie->dev),
+ rp->regs.start + SZ_1M,
+ rp->regs.end + SZ_1M);
+ if (!rp_res)
+ return -ENOMEM;
+
+ map_io_sections(rp->regs.start,
+ (void *)rp_res->start, SZ_1M);
+
+ rp->regs.start = rp_res->start;
+ rp->regs.end = rp_res->end;
+ } else {
+ rp_res = request_iomem_region(dev_name(pcie->dev),
+ rp->regs.start, rp->regs.end);
+ if (!rp_res)
+ return -ENOMEM;
+ }
+
+ INIT_LIST_HEAD(&rp->list);
+ rp->index = index;
+ rp->lanes = value;
+ rp->pcie = pcie;
+
+ rp->base = (void __force __iomem *)rp->regs.start;
+ if (IS_ERR(rp->base))
+ return PTR_ERR(rp->base);
+
+ list_add_tail(&rp->list, &pcie->ports);
+ }
+
+ err = tegra_pcie_get_xbar_config(pcie, lanes, &pcie->xbar_config);
+ if (err < 0) {
+ dev_err(pcie->dev, "invalid lane configuration\n");
+ return err;
+ }
+
+ return 0;
+}
+
+/*
+ * FIXME: If there are no PCIe cards attached, then calling this function
+ * can result in the increase of the bootup time as there are big timeout
+ * loops.
+ */
+#define TEGRA_PCIE_LINKUP_TIMEOUT 200 /* up to 1.2 seconds */
+static bool tegra_pcie_port_check_link(struct tegra_pcie_port *port)
+{
+ unsigned int timeout;
+ unsigned int retries = 2;
+ u32 value;
+
+ /* override presence detection */
+ value = readl(port->base + RP_PRIV_MISC);
+ value &= ~RP_PRIV_MISC_PRSNT_MAP_EP_ABSNT;
+ value |= RP_PRIV_MISC_PRSNT_MAP_EP_PRSNT;
+ writel(value, port->base + RP_PRIV_MISC);
+
+ do {
+ timeout = wait_on_timeout(50 * MSECOND,
+ readl(port->regs.start + RP_VEND_XP) & RP_VEND_XP_DL_UP);
+
+ if (timeout) {
+ dev_dbg(port->pcie->dev, "link %u down, retrying\n",
+ port->index);
+ goto retry;
+ }
+
+ timeout = wait_on_timeout(200 * MSECOND,
+ readl(port->regs.start + RP_LINK_CONTROL_STATUS) &
+ RP_LINK_CONTROL_STATUS_DL_LINK_ACTIVE);
+
+ if (!timeout)
+ return true;
+
+retry:
+ tegra_pcie_port_reset(port);
+ } while (--retries);
+
+ return false;
+}
+
+static int tegra_pcie_enable(struct tegra_pcie *pcie)
+{
+ struct tegra_pcie_port *port, *tmp;
+
+ list_for_each_entry_safe(port, tmp, &pcie->ports, list) {
+ dev_dbg(pcie->dev, "probing port %u, using %u lanes\n",
+ port->index, port->lanes);
+
+ tegra_pcie_port_enable(port);
+
+ if (tegra_pcie_port_check_link(port))
+ continue;
+
+ dev_dbg(pcie->dev, "link %u down, ignoring\n", port->index);
+
+ tegra_pcie_port_disable(port);
+ tegra_pcie_port_free(port);
+ }
+
+ pcie->pci.parent = pcie->dev;
+ pcie->pci.pci_ops = &tegra_pcie_ops;
+ pcie->pci.mem_resource = &pcie->mem;
+ pcie->pci.mem_pref_resource = &pcie->prefetch;
+ pcie->pci.io_resource = &pcie->io;
+
+ register_pci_controller(&pcie->pci);
+
+ return 0;
+}
+
+static const struct tegra_pcie_soc_data tegra20_pcie_data = {
+ .num_ports = 2,
+ .msi_base_shift = 0,
+ .pads_pll_ctl = PADS_PLL_CTL_TEGRA20,
+ .tx_ref_sel = PADS_PLL_CTL_TXCLKREF_DIV10,
+ .has_pex_clkreq_en = false,
+ .has_pex_bias_ctrl = false,
+ .has_intr_prsnt_sense = false,
+ .has_avdd_supply = false,
+ .has_cml_clk = false,
+ .has_gen2 = false,
+};
+
+static const struct tegra_pcie_soc_data tegra30_pcie_data = {
+ .num_ports = 3,
+ .msi_base_shift = 8,
+ .pads_pll_ctl = PADS_PLL_CTL_TEGRA30,
+ .tx_ref_sel = PADS_PLL_CTL_TXCLKREF_BUF_EN,
+ .has_pex_clkreq_en = true,
+ .has_pex_bias_ctrl = true,
+ .has_intr_prsnt_sense = true,
+ .has_avdd_supply = true,
+ .has_cml_clk = true,
+ .has_gen2 = false,
+};
+
+static const struct tegra_pcie_soc_data tegra124_pcie_data = {
+ .num_ports = 2,
+ .msi_base_shift = 8,
+ .pads_pll_ctl = PADS_PLL_CTL_TEGRA30,
+ .tx_ref_sel = PADS_PLL_CTL_TXCLKREF_BUF_EN,
+ .has_pex_clkreq_en = true,
+ .has_pex_bias_ctrl = true,
+ .has_intr_prsnt_sense = true,
+ .has_cml_clk = true,
+ .has_gen2 = true,
+};
+
+static __maybe_unused struct of_device_id tegra_pcie_of_match[] = {
+ {
+ .compatible = "nvidia,tegra124-pcie",
+ .data = (unsigned long)&tegra124_pcie_data
+ }, {
+ .compatible = "nvidia,tegra30-pcie",
+ .data = (unsigned long)&tegra30_pcie_data
+ }, {
+ .compatible = "nvidia,tegra20-pcie",
+ .data = (unsigned long)&tegra20_pcie_data
+ }, {
+ /* sentinel */
+ },
+};
+
+static int tegra_pcie_probe(struct device_d *dev)
+{
+ struct tegra_pcie *pcie;
+ int err;
+
+ pcie = kzalloc(sizeof(*pcie), GFP_KERNEL);
+ if (!pcie)
+ return -ENOMEM;
+
+ INIT_LIST_HEAD(&pcie->buses);
+ INIT_LIST_HEAD(&pcie->ports);
+ dev_get_drvdata(dev, (unsigned long *)&pcie->soc_data);
+ pcie->dev = dev;
+
+ err = tegra_pcie_parse_dt(pcie);
+ if (err < 0) {
+ printk("parse DT failed\n");
+ return err;
+ }
+
+ err = tegra_pcie_get_resources(pcie);
+ if (err < 0) {
+ dev_err(dev, "failed to request resources: %d\n", err);
+ return err;
+ }
+
+ err = tegra_pcie_enable_controller(pcie);
+ if (err)
+ goto put_resources;
+
+ /* setup the AFI address translations */
+ tegra_pcie_setup_translations(pcie);
+
+ err = tegra_pcie_enable(pcie);
+ if (err < 0) {
+ dev_err(dev, "failed to enable PCIe ports: %d\n", err);
+ goto put_resources;
+ }
+
+ return 0;
+
+put_resources:
+ tegra_pcie_put_resources(pcie);
+ return err;
+}
+
+static struct driver_d tegra_pcie_driver = {
+ .name = "tegra-pcie",
+ .of_compatible = DRV_OF_COMPAT(tegra_pcie_of_match),
+ .probe = tegra_pcie_probe,
+};
+device_platform_driver(tegra_pcie_driver);
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index a1b7680254..ba9d097230 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -12,6 +12,9 @@ static struct pci_controller *hose_head, **hose_tail = &hose_head;
LIST_HEAD(pci_root_buses);
EXPORT_SYMBOL(pci_root_buses);
static u8 bus_index;
+static resource_size_t last_mem;
+static resource_size_t last_mem_pref;
+static resource_size_t last_io;
static struct pci_bus *pci_alloc_bus(void)
{
@@ -37,14 +40,32 @@ void register_pci_controller(struct pci_controller *hose)
bus = pci_alloc_bus();
hose->bus = bus;
+ bus->parent = hose->parent;
bus->host = hose;
bus->ops = hose->pci_ops;
- bus->resource[0] = hose->mem_resource;
- bus->resource[1] = hose->io_resource;
+ bus->resource[PCI_BUS_RESOURCE_MEM] = hose->mem_resource;
+ bus->resource[PCI_BUS_RESOURCE_MEM_PREF] = hose->mem_pref_resource;
+ bus->resource[PCI_BUS_RESOURCE_IO] = hose->io_resource;
bus->number = bus_index++;
if (hose->set_busno)
hose->set_busno(hose, bus->number);
+
+ if (bus->resource[PCI_BUS_RESOURCE_MEM])
+ last_mem = bus->resource[PCI_BUS_RESOURCE_MEM]->start;
+ else
+ last_mem = 0;
+
+ if (bus->resource[PCI_BUS_RESOURCE_MEM])
+ last_mem_pref = bus->resource[PCI_BUS_RESOURCE_MEM_PREF]->start;
+ else
+ last_mem_pref = 0;
+
+ if (bus->resource[PCI_BUS_RESOURCE_IO])
+ last_io = bus->resource[PCI_BUS_RESOURCE_IO]->start;
+ else
+ last_io = 0;
+
pci_scan_bus(bus);
list_add_tail(&bus->node, &pci_root_buses);
@@ -111,27 +132,162 @@ static struct pci_dev *alloc_pci_dev(void)
return dev;
}
+static void setup_device(struct pci_dev *dev, int max_bar)
+{
+ int bar, size;
+ u32 mask;
+ u8 cmd;
+
+ pci_read_config_byte(dev, PCI_COMMAND, &cmd);
+ pci_write_config_byte(dev, PCI_COMMAND,
+ cmd & ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY));
+
+ for (bar = 0; bar < max_bar; bar++) {
+ resource_size_t last_addr;
+
+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, 0xfffffffe);
+ pci_read_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, &mask);
+
+ if (mask == 0 || mask == 0xffffffff) {
+ DBG(" PCI: pbar%d set bad mask\n", bar);
+ continue;
+ }
+
+ if (mask & 0x01) { /* IO */
+ size = -(mask & 0xfffffffe);
+ DBG(" PCI: pbar%d: mask=%08x io %d bytes\n", bar, mask, size);
+ if (last_io + size >
+ dev->bus->resource[PCI_BUS_RESOURCE_IO]->end) {
+ DBG("BAR does not fit within bus IO res\n");
+ return;
+ }
+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, last_io);
+ dev->resource[bar].flags = IORESOURCE_IO;
+ last_addr = last_io;
+ last_io += size;
+ } else if ((mask & PCI_BASE_ADDRESS_MEM_PREFETCH) &&
+ last_mem_pref) /* prefetchable MEM */ {
+ size = -(mask & 0xfffffff0);
+ DBG(" PCI: pbar%d: mask=%08x P memory %d bytes\n",
+ bar, mask, size);
+ if (last_mem_pref + size >
+ dev->bus->resource[PCI_BUS_RESOURCE_MEM_PREF]->end) {
+ DBG("BAR does not fit within bus p-mem res\n");
+ return;
+ }
+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, last_mem_pref);
+ dev->resource[bar].flags = IORESOURCE_MEM |
+ IORESOURCE_PREFETCH;
+ last_addr = last_mem_pref;
+ last_mem_pref += size;
+ } else { /* non-prefetch MEM */
+ size = -(mask & 0xfffffff0);
+ DBG(" PCI: pbar%d: mask=%08x NP memory %d bytes\n",
+ bar, mask, size);
+ if (last_mem + size >
+ dev->bus->resource[PCI_BUS_RESOURCE_MEM]->end) {
+ DBG("BAR does not fit within bus np-mem res\n");
+ return;
+ }
+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, last_mem);
+ dev->resource[bar].flags = IORESOURCE_MEM;
+ last_addr = last_mem;
+ last_mem += size;
+ }
+
+ dev->resource[bar].start = last_addr;
+ dev->resource[bar].end = last_addr + size - 1;
+
+ if ((mask & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
+ PCI_BASE_ADDRESS_MEM_TYPE_64) {
+ dev->resource[bar].flags |= IORESOURCE_MEM_64;
+ pci_write_config_dword(dev,
+ PCI_BASE_ADDRESS_1 + bar * 4, 0);
+ bar++;
+ }
+ }
+
+ pci_write_config_byte(dev, PCI_COMMAND, cmd);
+ list_add_tail(&dev->bus_list, &dev->bus->devices);
+}
+
+static void prescan_setup_bridge(struct pci_dev *dev)
+{
+ u16 cmdstat;
+
+ pci_read_config_word(dev, PCI_COMMAND, &cmdstat);
+
+ /* Configure bus number registers */
+ pci_write_config_byte(dev, PCI_PRIMARY_BUS, dev->bus->number);
+ pci_write_config_byte(dev, PCI_SECONDARY_BUS, dev->subordinate->number);
+ pci_write_config_byte(dev, PCI_SUBORDINATE_BUS, 0xff);
+
+ if (last_mem) {
+ /* Set up memory and I/O filter limits, assume 32-bit I/O space */
+ pci_write_config_word(dev, PCI_MEMORY_BASE,
+ (last_mem & 0xfff00000) >> 16);
+ cmdstat |= PCI_COMMAND_MEMORY;
+ }
+
+ if (last_mem_pref) {
+ /* Set up memory and I/O filter limits, assume 32-bit I/O space */
+ pci_write_config_word(dev, PCI_PREF_MEMORY_BASE,
+ (last_mem_pref & 0xfff00000) >> 16);
+ cmdstat |= PCI_COMMAND_MEMORY;
+ } else {
+
+ /* We don't support prefetchable memory for now, so disable */
+ pci_write_config_word(dev, PCI_PREF_MEMORY_BASE, 0x1000);
+ pci_write_config_word(dev, PCI_PREF_MEMORY_LIMIT, 0x0);
+ }
+
+ if (last_io) {
+ pci_write_config_byte(dev, PCI_IO_BASE,
+ (last_io & 0x0000f000) >> 8);
+ pci_write_config_word(dev, PCI_IO_BASE_UPPER16,
+ (last_io & 0xffff0000) >> 16);
+ cmdstat |= PCI_COMMAND_IO;
+ }
+
+ /* Enable memory and I/O accesses, enable bus master */
+ pci_write_config_word(dev, PCI_COMMAND, cmdstat | PCI_COMMAND_MASTER);
+}
+
+static void postscan_setup_bridge(struct pci_dev *dev)
+{
+ /* limit subordinate to last used bus number */
+ pci_write_config_byte(dev, PCI_SUBORDINATE_BUS, bus_index - 1);
+
+ if (last_mem)
+ pci_write_config_word(dev, PCI_MEMORY_LIMIT,
+ ((last_mem - 1) & 0xfff00000) >> 16);
+
+ if (last_mem_pref)
+ pci_write_config_word(dev, PCI_PREF_MEMORY_LIMIT,
+ ((last_mem_pref - 1) & 0xfff00000) >> 16);
+
+ if (last_io) {
+ pci_write_config_byte(dev, PCI_IO_LIMIT,
+ ((last_io - 1) & 0x0000f000) >> 8);
+ pci_write_config_word(dev, PCI_IO_LIMIT_UPPER16,
+ ((last_io - 1) & 0xffff0000) >> 16);
+ }
+}
+
unsigned int pci_scan_bus(struct pci_bus *bus)
{
+ struct pci_dev *dev;
+ struct pci_bus *child_bus;
unsigned int devfn, l, max, class;
unsigned char cmd, tmp, hdr_type, is_multi = 0;
- struct pci_dev *dev;
- resource_size_t last_mem;
- resource_size_t last_io;
-
- /* FIXME: use res_start() */
- last_mem = bus->resource[0]->start;
- last_io = bus->resource[1]->start;
DBG("pci_scan_bus for bus %d\n", bus->number);
- DBG(" last_io = 0x%08x, last_mem = 0x%08x\n", last_io, last_mem);
+ DBG(" last_io = 0x%08x, last_mem = 0x%08x, last_mem_pref = 0x%08x\n",
+ last_io, last_mem, last_mem_pref);
+
max = bus->secondary;
for (devfn = 0; devfn < 0xff; ++devfn) {
- int bar;
- u32 old_bar, mask;
- int size;
-
if (PCI_FUNC(devfn) && !is_multi) {
/* not a multi-function device */
continue;
@@ -154,6 +310,7 @@ unsigned int pci_scan_bus(struct pci_bus *bus)
dev->devfn = devfn;
dev->vendor = l & 0xffff;
dev->device = (l >> 16) & 0xffff;
+ dev->dev.parent = bus->parent;
/* non-destructively determine if device can be a master: */
pci_read_config_byte(dev, PCI_COMMAND, &cmd);
@@ -169,9 +326,11 @@ unsigned int pci_scan_bus(struct pci_bus *bus)
dev->hdr_type = hdr_type;
DBG("PCI: class = %08x, hdr_type = %08x\n", class, hdr_type);
+ DBG("PCI: %02x:%02x [%04x:%04x]\n", bus->number, dev->devfn,
+ dev->vendor, dev->device);
- switch (hdr_type & 0x7f) { /* header type */
- case PCI_HEADER_TYPE_NORMAL: /* standard header */
+ switch (hdr_type & 0x7f) {
+ case PCI_HEADER_TYPE_NORMAL:
if (class == PCI_CLASS_BRIDGE_PCI)
goto bad;
@@ -181,70 +340,48 @@ unsigned int pci_scan_bus(struct pci_bus *bus)
*/
pci_read_config_dword(dev, PCI_ROM_ADDRESS, &l);
dev->rom_address = (l == 0xffffffff) ? 0 : l;
+
+ setup_device(dev, 6);
+ break;
+ case PCI_HEADER_TYPE_BRIDGE:
+ setup_device(dev, 2);
+
+ child_bus = pci_alloc_bus();
+ /* inherit parent properties */
+ child_bus->host = bus->host;
+ child_bus->ops = bus->host->pci_ops;
+ child_bus->resource[PCI_BUS_RESOURCE_MEM] =
+ bus->resource[PCI_BUS_RESOURCE_MEM];
+ child_bus->resource[PCI_BUS_RESOURCE_MEM_PREF] =
+ bus->resource[PCI_BUS_RESOURCE_MEM_PREF];
+ child_bus->resource[PCI_BUS_RESOURCE_IO] =
+ bus->resource[PCI_BUS_RESOURCE_IO];
+
+ child_bus->parent = &dev->dev;
+ child_bus->number = bus_index++;
+ list_add_tail(&child_bus->node, &bus->children);
+ dev->subordinate = child_bus;
+
+ prescan_setup_bridge(dev);
+ pci_scan_bus(child_bus);
+ postscan_setup_bridge(dev);
+ /* first activate bridge then all devices on it's bus */
+ pci_register_device(dev);
+ list_for_each_entry(dev, &child_bus->devices, bus_list)
+ if (!dev->subordinate)
+ pci_register_device(dev);
break;
- default: /* unknown header */
+ default:
bad:
printk(KERN_ERR "PCI: %02x:%02x [%04x/%04x/%06x] has unknown header type %02x, ignoring.\n",
bus->number, dev->devfn, dev->vendor, dev->device, class, hdr_type);
continue;
}
- DBG("PCI: %02x:%02x [%04x/%04x]\n", bus->number, dev->devfn, dev->vendor, dev->device);
-
if (class == PCI_CLASS_BRIDGE_HOST) {
DBG("PCI: skip pci host bridge\n");
continue;
}
-
- pci_read_config_byte(dev, PCI_COMMAND, &cmd);
- pci_write_config_byte(dev, PCI_COMMAND,
- cmd & ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY));
-
- for (bar = 0; bar < 6; bar++) {
- resource_size_t last_addr;
-
- pci_read_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, &old_bar);
- pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, 0xfffffffe);
- pci_read_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, &mask);
- pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, old_bar);
-
- if (mask == 0 || mask == 0xffffffff) {
- DBG(" PCI: pbar%d set bad mask\n", bar);
- continue;
- }
-
- if (mask & 0x01) { /* IO */
- size = -(mask & 0xfffffffe);
- DBG(" PCI: pbar%d: mask=%08x io %d bytes\n", bar, mask, size);
- pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, last_io);
- dev->resource[bar].flags = IORESOURCE_IO;
- last_addr = last_io;
- last_io += size;
- } else { /* MEM */
- size = -(mask & 0xfffffff0);
- DBG(" PCI: pbar%d: mask=%08x memory %d bytes\n", bar, mask, size);
- pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + bar * 4, last_mem);
- dev->resource[bar].flags = IORESOURCE_MEM;
- last_addr = last_mem;
- last_mem += size;
-
- if ((mask & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
- PCI_BASE_ADDRESS_MEM_TYPE_64) {
- dev->resource[bar].flags |= IORESOURCE_MEM_64;
- pci_write_config_dword(dev,
- PCI_BASE_ADDRESS_1 + bar * 4, 0);
- }
- }
-
- dev->resource[bar].start = last_addr;
- dev->resource[bar].end = last_addr + size - 1;
- if (dev->resource[bar].flags & IORESOURCE_MEM_64)
- bar++;
- }
-
- pci_write_config_byte(dev, PCI_COMMAND, cmd);
- list_add_tail(&dev->bus_list, &bus->devices);
- pci_register_device(dev);
}
/*
@@ -254,6 +391,7 @@ unsigned int pci_scan_bus(struct pci_bus *bus)
*
* Return how far we've got finding sub-buses.
*/
+ max = bus_index;
DBG("PCI: pci_scan_bus returning with max=%02x\n", max);
return max;
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
new file mode 100644
index 0000000000..e9461e1a25
--- /dev/null
+++ b/drivers/phy/Kconfig
@@ -0,0 +1,18 @@
+#
+# PHY
+#
+
+menu "PHY Subsystem"
+
+config GENERIC_PHY
+ bool "PHY Core"
+ help
+ Generic PHY support.
+
+ This framework is designed to provide a generic interface for PHY
+ devices present in the kernel. This layer will have the generic
+ API by which phy drivers can create PHY using the phy framework and
+ phy users can obtain reference to the PHY. All the users of this
+ framework should select this config.
+
+endmenu
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
new file mode 100644
index 0000000000..74514aeaed
--- /dev/null
+++ b/drivers/phy/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for the phy drivers.
+#
+
+obj-$(CONFIG_GENERIC_PHY) += phy-core.o
diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c
new file mode 100644
index 0000000000..67af14f680
--- /dev/null
+++ b/drivers/phy/phy-core.c
@@ -0,0 +1,318 @@
+/*
+ * phy-core.c -- Generic Phy framework.
+ *
+ * Copyright (C) 2014 Lucas Stach <l.stach@pengutronix.de>
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
+ *
+ * Author: Kishon Vijay Abraham I <kishon@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <linux/phy/phy.h>
+
+static LIST_HEAD(phy_provider_list);
+static int phy_ida;
+
+/**
+ * phy_create() - create a new phy
+ * @dev: device that is creating the new phy
+ * @node: device node of the phy
+ * @ops: function pointers for performing phy operations
+ * @init_data: contains the list of PHY consumers or NULL
+ *
+ * Called to create a phy using phy framework.
+ */
+struct phy *phy_create(struct device_d *dev, struct device_node *node,
+ const struct phy_ops *ops,
+ struct phy_init_data *init_data)
+{
+ int ret;
+ int id;
+ struct phy *phy;
+
+ if (WARN_ON(!dev))
+ return ERR_PTR(-EINVAL);
+
+ phy = kzalloc(sizeof(*phy), GFP_KERNEL);
+ if (!phy)
+ return ERR_PTR(-ENOMEM);
+
+ id = phy_ida++;
+
+ snprintf(phy->dev.name, MAX_DRIVER_NAME, "phy");
+ phy->dev.id = id;
+ phy->dev.parent = dev;
+ phy->dev.device_node = node ?: dev->device_node;
+ phy->id = id;
+ phy->ops = ops;
+ phy->init_data = init_data;
+
+ ret = register_device(&phy->dev);
+ if (ret)
+ goto free_ida;
+
+ return phy;
+
+free_ida:
+ phy_ida--;
+ kfree(phy);
+ return ERR_PTR(ret);
+}
+
+/**
+ * __of_phy_provider_register() - create/register phy provider with the framework
+ * @dev: struct device of the phy provider
+ * @owner: the module owner containing of_xlate
+ * @of_xlate: function pointer to obtain phy instance from phy provider
+ *
+ * Creates struct phy_provider from dev and of_xlate function pointer.
+ * This is used in the case of dt boot for finding the phy instance from
+ * phy provider.
+ */
+struct phy_provider *__of_phy_provider_register(struct device_d *dev,
+ struct phy * (*of_xlate)(struct device_d *dev,
+ struct of_phandle_args *args))
+{
+ struct phy_provider *phy_provider;
+
+ phy_provider = kzalloc(sizeof(*phy_provider), GFP_KERNEL);
+ if (!phy_provider)
+ return ERR_PTR(-ENOMEM);
+
+ phy_provider->dev = dev;
+ phy_provider->of_xlate = of_xlate;
+
+ list_add_tail(&phy_provider->list, &phy_provider_list);
+
+ return phy_provider;
+}
+
+/**
+ * of_phy_provider_unregister() - unregister phy provider from the framework
+ * @phy_provider: phy provider returned by of_phy_provider_register()
+ *
+ * Removes the phy_provider created using of_phy_provider_register().
+ */
+void of_phy_provider_unregister(struct phy_provider *phy_provider)
+{
+ if (IS_ERR(phy_provider))
+ return;
+
+ list_del(&phy_provider->list);
+ kfree(phy_provider);
+}
+
+int phy_init(struct phy *phy)
+{
+ int ret;
+
+ if (!phy)
+ return 0;
+
+ if (phy->init_count == 0 && phy->ops->init) {
+ ret = phy->ops->init(phy);
+ if (ret < 0) {
+ dev_err(&phy->dev, "phy init failed --> %d\n", ret);
+ return ret;
+ }
+ }
+ ++phy->init_count;
+
+ return 0;
+}
+
+int phy_exit(struct phy *phy)
+{
+ int ret;
+
+ if (!phy)
+ return 0;
+
+ if (phy->init_count == 1 && phy->ops->exit) {
+ ret = phy->ops->exit(phy);
+ if (ret < 0) {
+ dev_err(&phy->dev, "phy exit failed --> %d\n", ret);
+ return ret;
+ }
+ }
+ --phy->init_count;
+
+ return 0;
+}
+
+int phy_power_on(struct phy *phy)
+{
+ int ret;
+
+ if (!phy)
+ return 0;
+
+ if (phy->pwr) {
+ ret = regulator_enable(phy->pwr);
+ if (ret)
+ return ret;
+ }
+
+ if (phy->power_count == 0 && phy->ops->power_on) {
+ ret = phy->ops->power_on(phy);
+ if (ret < 0) {
+ dev_err(&phy->dev, "phy poweron failed --> %d\n", ret);
+ goto out;
+ }
+ } else {
+ ret = 0; /* Override possible ret == -ENOTSUPP */
+ }
+ ++phy->power_count;
+
+ return 0;
+
+out:
+ if (phy->pwr)
+ regulator_disable(phy->pwr);
+
+ return ret;
+}
+
+int phy_power_off(struct phy *phy)
+{
+ int ret;
+
+ if (!phy)
+ return 0;
+
+ if (phy->power_count == 1 && phy->ops->power_off) {
+ ret = phy->ops->power_off(phy);
+ if (ret < 0) {
+ dev_err(&phy->dev, "phy poweroff failed --> %d\n", ret);
+ return ret;
+ }
+ }
+ --phy->power_count;
+
+ if (phy->pwr)
+ regulator_disable(phy->pwr);
+
+ return 0;
+}
+
+static struct phy_provider *of_phy_provider_lookup(struct device_node *node)
+{
+ struct phy_provider *phy_provider;
+ struct device_node *child;
+
+ list_for_each_entry(phy_provider, &phy_provider_list, list) {
+ if (phy_provider->dev->device_node == node)
+ return phy_provider;
+
+ for_each_child_of_node(phy_provider->dev->device_node, child)
+ if (child == node)
+ return phy_provider;
+ }
+
+ return ERR_PTR(-ENODEV);
+}
+
+/**
+ * _of_phy_get() - lookup and obtain a reference to a phy by phandle
+ * @np: device_node for which to get the phy
+ * @index: the index of the phy
+ *
+ * Returns the phy associated with the given phandle value,
+ * after getting a refcount to it or -ENODEV if there is no such phy or
+ * -EPROBE_DEFER if there is a phandle to the phy, but the device is
+ * not yet loaded. This function uses of_xlate call back function provided
+ * while registering the phy_provider to find the phy instance.
+ */
+static struct phy *_of_phy_get(struct device_node *np, int index)
+{
+ int ret;
+ struct phy_provider *phy_provider;
+ struct of_phandle_args args;
+
+ ret = of_parse_phandle_with_args(np, "phys", "#phy-cells",
+ index, &args);
+ if (ret)
+ return ERR_PTR(-ENODEV);
+
+ phy_provider = of_phy_provider_lookup(args.np);
+ if (IS_ERR(phy_provider)) {
+ return ERR_PTR(-ENODEV);
+ }
+
+ return phy_provider->of_xlate(phy_provider->dev, &args);
+}
+
+/**
+ * of_phy_get() - lookup and obtain a reference to a phy using a device_node.
+ * @np: device_node for which to get the phy
+ * @con_id: name of the phy from device's point of view
+ *
+ * Returns the phy driver, after getting a refcount to it; or
+ * -ENODEV if there is no such phy. The caller is responsible for
+ * calling phy_put() to release that count.
+ */
+struct phy *of_phy_get(struct device_node *np, const char *con_id)
+{
+ int index = 0;
+
+ if (con_id)
+ index = of_property_match_string(np, "phy-names", con_id);
+
+ return _of_phy_get(np, index);
+}
+
+/**
+ * phy_get() - lookup and obtain a reference to a phy.
+ * @dev: device that requests this phy
+ * @string: the phy name as given in the dt data or the name of the controller
+ * port for non-dt case
+ *
+ * Returns the phy driver, after getting a refcount to it; or
+ * -ENODEV if there is no such phy. The caller is responsible for
+ * calling phy_put() to release that count.
+ */
+struct phy *phy_get(struct device_d *dev, const char *string)
+{
+ int index = 0;
+ struct phy *phy = ERR_PTR(-ENODEV);
+
+ if (string == NULL) {
+ dev_warn(dev, "missing string\n");
+ return ERR_PTR(-EINVAL);
+ }
+
+ if (dev->device_node) {
+ index = of_property_match_string(dev->device_node, "phy-names",
+ string);
+ phy = _of_phy_get(dev->device_node, index);
+ }
+
+ return phy;
+}
+
+/**
+ * phy_optional_get() - lookup and obtain a reference to an optional phy.
+ * @dev: device that requests this phy
+ * @string: the phy name as given in the dt data or the name of the controller
+ * port for non-dt case
+ *
+ * Returns the phy driver, after getting a refcount to it; or
+ * NULL if there is no such phy. The caller is responsible for
+ * calling phy_put() to release that count.
+ */
+struct phy *phy_optional_get(struct device_d *dev, const char *string)
+{
+ struct phy *phy = phy_get(dev, string);
+
+ if (PTR_ERR(phy) == -ENODEV)
+ phy = NULL;
+
+ return phy;
+}
+
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 770fb2d414..4cbc167cd0 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -60,6 +60,14 @@ config PINCTRL_TEGRA30
help
The pinmux controller found on the Tegra 30+ line of SoCs.
+config PINCTRL_TEGRA_XUSB
+ bool
+ default y if ARCH_TEGRA_124_SOC
+ select GENERIC_PHY
+ help
+ The pinmux controller found on the Tegra 124 line of SoCs used for
+ the SerDes lanes.
+
source drivers/pinctrl/mvebu/Kconfig
endif
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index 3ea8649efb..724e6d7d06 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -7,5 +7,6 @@ obj-$(CONFIG_PINCTRL_ROCKCHIP) += pinctrl-rockchip.o
obj-$(CONFIG_PINCTRL_SINGLE) += pinctrl-single.o
obj-$(CONFIG_PINCTRL_TEGRA20) += pinctrl-tegra20.o
obj-$(CONFIG_PINCTRL_TEGRA30) += pinctrl-tegra30.o
+obj-$(CONFIG_PINCTRL_TEGRA_XUSB) += pinctrl-tegra-xusb.o
obj-$(CONFIG_ARCH_MVEBU) += mvebu/
diff --git a/drivers/pinctrl/pinctrl-tegra-xusb.c b/drivers/pinctrl/pinctrl-tegra-xusb.c
new file mode 100644
index 0000000000..05cdecbabf
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-tegra-xusb.c
@@ -0,0 +1,519 @@
+/*
+ * Copyright (C) 2014 Lucas Stach <l.stach@pengutronix.de>
+ *
+ * Partly based on code
+ * Copyright (C) 2014, 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 <clock.h>
+#include <init.h>
+#include <io.h>
+#include <malloc.h>
+#include <pinctrl.h>
+#include <linux/err.h>
+#include <linux/reset.h>
+#include <linux/phy/phy.h>
+
+#include <dt-bindings/pinctrl/pinctrl-tegra-xusb.h>
+
+#define XUSB_PADCTL_ELPG_PROGRAM 0x01c
+#define XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN (1 << 26)
+#define XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN_EARLY (1 << 25)
+#define XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN (1 << 24)
+
+#define XUSB_PADCTL_IOPHY_PLL_P0_CTL1 0x040
+#define XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL0_LOCKDET (1 << 19)
+#define XUSB_PADCTL_IOPHY_PLL_P0_CTL1_REFCLK_SEL_MASK (0xf << 12)
+#define XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL_RST (1 << 1)
+
+#define XUSB_PADCTL_IOPHY_PLL_P0_CTL2 0x044
+#define XUSB_PADCTL_IOPHY_PLL_P0_CTL2_REFCLKBUF_EN (1 << 6)
+#define XUSB_PADCTL_IOPHY_PLL_P0_CTL2_TXCLKREF_EN (1 << 5)
+#define XUSB_PADCTL_IOPHY_PLL_P0_CTL2_TXCLKREF_SEL (1 << 4)
+
+#define XUSB_PADCTL_IOPHY_PLL_S0_CTL1 0x138
+#define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_LOCKDET (1 << 27)
+#define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_MODE (1 << 24)
+#define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_PWR_OVRD (1 << 3)
+#define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_RST (1 << 1)
+#define XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_IDDQ (1 << 0)
+
+#define XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1 0x148
+#define XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ_OVRD (1 << 1)
+#define XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ (1 << 0)
+
+struct tegra_xusb_padctl_soc {
+ const struct tegra_xusb_padctl_lane *lanes;
+ unsigned int num_lanes;
+};
+
+struct tegra_xusb_padctl_lane {
+ const char *name;
+
+ unsigned int offset;
+ unsigned int shift;
+ unsigned int mask;
+ unsigned int iddq;
+
+ const char **funcs;
+ unsigned int num_funcs;
+};
+
+struct tegra_xusb_padctl {
+ struct device_d *dev;
+ void __iomem *regs;
+ struct reset_control *rst;
+
+ const struct tegra_xusb_padctl_soc *soc;
+ struct pinctrl_device pinctrl;
+
+ struct phy_provider *provider;
+ struct phy *phys[2];
+
+ unsigned int enable;
+};
+
+static inline void padctl_writel(struct tegra_xusb_padctl *padctl, u32 value,
+ unsigned long offset)
+{
+ writel(value, padctl->regs + offset);
+}
+
+static inline u32 padctl_readl(struct tegra_xusb_padctl *padctl,
+ unsigned long offset)
+{
+ return readl(padctl->regs + offset);
+}
+
+static int tegra_xusb_padctl_enable(struct tegra_xusb_padctl *padctl)
+{
+ u32 value;
+
+ if (padctl->enable++ > 0)
+ return 0;
+
+ value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);
+ value &= ~XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN;
+ padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);
+
+ udelay(100);
+
+ value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);
+ value &= ~XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN_EARLY;
+ padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);
+
+ udelay(100);
+
+ value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);
+ value &= ~XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN;
+ padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);
+
+ return 0;
+}
+
+static int tegra_xusb_padctl_disable(struct tegra_xusb_padctl *padctl)
+{
+ u32 value;
+
+ if (WARN_ON(padctl->enable == 0))
+ return 0;
+
+ if (--padctl->enable > 0)
+ return 0;
+
+ value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);
+ value |= XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_VCORE_DOWN;
+ padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);
+
+ udelay(100);
+
+ value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);
+ value |= XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN_EARLY;
+ padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);
+
+ udelay(100);
+
+ value = padctl_readl(padctl, XUSB_PADCTL_ELPG_PROGRAM);
+ value |= XUSB_PADCTL_ELPG_PROGRAM_AUX_MUX_LP0_CLAMP_EN;
+ padctl_writel(padctl, value, XUSB_PADCTL_ELPG_PROGRAM);
+
+ return 0;
+}
+
+static int tegra_xusb_phy_init(struct phy *phy)
+{
+ struct tegra_xusb_padctl *padctl = phy_get_drvdata(phy);
+
+ return tegra_xusb_padctl_enable(padctl);
+}
+
+static int tegra_xusb_phy_exit(struct phy *phy)
+{
+ struct tegra_xusb_padctl *padctl = phy_get_drvdata(phy);
+
+ return tegra_xusb_padctl_disable(padctl);
+}
+
+static int pcie_phy_power_on(struct phy *phy)
+{
+ struct tegra_xusb_padctl *padctl = phy_get_drvdata(phy);
+ int err;
+ u32 value;
+
+ value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL1);
+ value &= ~XUSB_PADCTL_IOPHY_PLL_P0_CTL1_REFCLK_SEL_MASK;
+ padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_P0_CTL1);
+
+ value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL2);
+ value |= XUSB_PADCTL_IOPHY_PLL_P0_CTL2_REFCLKBUF_EN |
+ XUSB_PADCTL_IOPHY_PLL_P0_CTL2_TXCLKREF_EN |
+ XUSB_PADCTL_IOPHY_PLL_P0_CTL2_TXCLKREF_SEL;
+ padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_P0_CTL2);
+
+ value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL1);
+ value |= XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL_RST;
+ padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_P0_CTL1);
+
+ err = wait_on_timeout(50 * MSECOND,
+ padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL1) &
+ XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL0_LOCKDET);
+
+ return err;
+}
+
+static int pcie_phy_power_off(struct phy *phy)
+{
+ struct tegra_xusb_padctl *padctl = phy_get_drvdata(phy);
+ u32 value;
+
+ value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_P0_CTL1);
+ value &= ~XUSB_PADCTL_IOPHY_PLL_P0_CTL1_PLL_RST;
+ padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_P0_CTL1);
+
+ return 0;
+}
+
+static const struct phy_ops pcie_phy_ops = {
+
+ .init = tegra_xusb_phy_init,
+ .exit = tegra_xusb_phy_exit,
+ .power_on = pcie_phy_power_on,
+ .power_off = pcie_phy_power_off,
+};
+
+static int sata_phy_power_on(struct phy *phy)
+{
+ struct tegra_xusb_padctl *padctl = phy_get_drvdata(phy);
+ int err;
+ u32 value;
+
+ value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1);
+ value &= ~XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ_OVRD;
+ value &= ~XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ;
+ padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1);
+
+ value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
+ value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_PWR_OVRD;
+ value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_IDDQ;
+ padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
+
+ value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
+ value |= XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_MODE;
+ padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
+
+ value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
+ value |= XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_RST;
+ padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
+
+ err = wait_on_timeout(50 * MSECOND,
+ padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1) &
+ XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_LOCKDET);
+
+ return err;
+}
+
+static int sata_phy_power_off(struct phy *phy)
+{
+ struct tegra_xusb_padctl *padctl = phy_get_drvdata(phy);
+ u32 value;
+
+ value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
+ value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_RST;
+ padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
+
+ value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
+ value &= ~XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL1_MODE;
+ padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
+
+ value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
+ value |= XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_PWR_OVRD;
+ value |= XUSB_PADCTL_IOPHY_PLL_S0_CTL1_PLL_IDDQ;
+ padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_PLL_S0_CTL1);
+
+ value = padctl_readl(padctl, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1);
+ value |= ~XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ_OVRD;
+ value |= ~XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1_IDDQ;
+ padctl_writel(padctl, value, XUSB_PADCTL_IOPHY_MISC_PAD_S0_CTL1);
+
+ return 0;
+}
+
+static const struct phy_ops sata_phy_ops = {
+
+ .init = tegra_xusb_phy_init,
+ .exit = tegra_xusb_phy_exit,
+ .power_on = sata_phy_power_on,
+ .power_off = sata_phy_power_off,
+};
+
+static struct phy *tegra_xusb_padctl_xlate(struct device_d *dev,
+ struct of_phandle_args *args)
+{
+ struct tegra_xusb_padctl *padctl = dev->priv;
+ unsigned int index = args->args[0];
+
+ if (args->args_count <= 0)
+ return ERR_PTR(-EINVAL);
+
+ if (index >= ARRAY_SIZE(padctl->phys))
+ return ERR_PTR(-EINVAL);
+
+ return padctl->phys[index];
+}
+
+static int pinctrl_tegra_xusb_set_state(struct pinctrl_device *pdev,
+ struct device_node *np)
+{
+ struct tegra_xusb_padctl *padctl =
+ container_of(pdev, struct tegra_xusb_padctl, pinctrl);
+ struct device_node *childnode;
+ int iddq = -1, i, j, k;
+ const char *lanes, *func = NULL;
+ const struct tegra_xusb_padctl_lane *lane = NULL;
+ u32 val;
+
+ /*
+ * 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_tegra_xusb_set_state(pdev, childnode);
+
+ /* read relevant state from devicetree */
+ of_property_read_string(np, "nvidia,function", &func);
+ of_property_read_u32_array(np, "nvidia,iddq", &iddq, 1);
+
+ /* iterate over all lanes referenced in the dt node */
+ for (i = 0; ; i++) {
+ if (of_property_read_string_index(np, "nvidia,lanes", i, &lanes))
+ break;
+
+ for (j = 0; j < padctl->soc->num_lanes; j++) {
+ if (!strcmp(lanes, padctl->soc->lanes[j].name)) {
+ lane = &padctl->soc->lanes[j];
+ break;
+ }
+ }
+ /* if no matching lane is found */
+ if (j == padctl->soc->num_lanes) {
+ /* nothing matching found, warn and bail out */
+ dev_warn(padctl->pinctrl.dev,
+ "invalid lane %s referenced in node %s\n",
+ lanes, np->name);
+ continue;
+ }
+
+ if (func) {
+ for (k = 0; k < lane->num_funcs; k++) {
+ if (!strcmp(func, lane->funcs[k]))
+ break;
+ }
+ if (k < lane->num_funcs) {
+ val = padctl_readl(padctl, lane->offset);
+ val &= ~(lane->mask << lane->shift);
+ val |= k << lane->shift;
+ padctl_writel(padctl, val, lane->offset);
+ } else {
+ dev_warn(padctl->pinctrl.dev,
+ "invalid function %s for lane %s in node %s\n",
+ func, lane->name, np->name);
+ }
+ }
+
+ if (iddq >= 0) {
+ if (lane->iddq) {
+ val = padctl_readl(padctl, lane->offset);
+ if (iddq)
+ val &= ~BIT(lane->iddq);
+ else
+ val |= BIT(lane->iddq);
+ padctl_writel(padctl, val, lane->offset);
+ } else {
+ dev_warn(padctl->pinctrl.dev,
+ "invalid iddq setting for lane %s in node %s\n",
+ lane->name, np->name);
+ }
+ }
+ }
+
+ return 0;
+}
+
+static struct pinctrl_ops pinctrl_tegra_xusb_ops = {
+ .set_state = pinctrl_tegra_xusb_set_state,
+};
+
+static int pinctrl_tegra_xusb_probe(struct device_d *dev)
+{
+ struct tegra_xusb_padctl *padctl;
+ struct phy *phy;
+ int err;
+
+ padctl = xzalloc(sizeof(*padctl));
+
+ dev->priv = padctl;
+ padctl->dev = dev;
+
+ dev_get_drvdata(dev, (unsigned long *)&padctl->soc);
+
+ padctl->regs = dev_request_mem_region(dev, 0);
+ if (IS_ERR(padctl->regs)) {
+ dev_err(dev, "Could not get iomem region\n");
+ return PTR_ERR(padctl->regs);
+ }
+
+ padctl->rst = reset_control_get(dev, NULL);
+ if (IS_ERR(padctl->rst))
+ return PTR_ERR(padctl->rst);
+
+ err = reset_control_deassert(padctl->rst);
+ if (err < 0)
+ return err;
+
+ padctl->pinctrl.dev = dev;
+ padctl->pinctrl.ops = &pinctrl_tegra_xusb_ops;
+
+ err = pinctrl_register(&padctl->pinctrl);
+ if (err) {
+ dev_err(dev, "failed to register pincontrol\n");
+ err = -ENODEV;
+ goto reset;
+ }
+
+ phy = phy_create(dev, NULL, &pcie_phy_ops, NULL);
+ if (IS_ERR(phy)) {
+ err = PTR_ERR(phy);
+ goto unregister;
+ }
+
+ padctl->phys[TEGRA_XUSB_PADCTL_PCIE] = phy;
+ phy_set_drvdata(phy, padctl);
+
+ phy = phy_create(dev, NULL, &sata_phy_ops, NULL);
+ if (IS_ERR(phy)) {
+ err = PTR_ERR(phy);
+ goto unregister;
+ }
+
+ padctl->phys[TEGRA_XUSB_PADCTL_SATA] = phy;
+ phy_set_drvdata(phy, padctl);
+
+ padctl->provider = of_phy_provider_register(dev, tegra_xusb_padctl_xlate);
+ if (IS_ERR(padctl->provider)) {
+ err = PTR_ERR(padctl->provider);
+ dev_err(dev, "failed to register PHYs: %d\n", err);
+ goto unregister;
+ }
+
+ return 0;
+
+unregister:
+ pinctrl_unregister(&padctl->pinctrl);
+reset:
+ reset_control_assert(padctl->rst);
+ return err;
+}
+
+static const char *tegra124_otg_functions[] = {
+ "snps",
+ "xusb",
+ "uart",
+ "rsvd",
+};
+
+static const char *tegra124_usb_functions[] = {
+ "snps",
+ "xusb",
+};
+
+static const char *tegra124_pci_functions[] = {
+ "pcie",
+ "usb3",
+ "sata",
+ "rsvd",
+};
+
+#define TEGRA124_LANE(_name, _offs, _shift, _mask, _iddq, _funcs, _num) \
+ { \
+ .name = _name, \
+ .offset = _offs, \
+ .shift = _shift, \
+ .mask = _mask, \
+ .iddq = _iddq, \
+ .num_funcs = _num, \
+ .funcs = tegra124_##_funcs##_functions, \
+ }
+
+static const struct tegra_xusb_padctl_lane tegra124_lanes[] = {
+ TEGRA124_LANE("otg-0", 0x004, 0, 0x3, 0, otg, 4),
+ TEGRA124_LANE("otg-1", 0x004, 2, 0x3, 0, otg, 4),
+ TEGRA124_LANE("otg-2", 0x004, 4, 0x3, 0, otg, 4),
+ TEGRA124_LANE("ulpi-0", 0x004, 12, 0x1, 0, usb, 2),
+ TEGRA124_LANE("hsic-0", 0x004, 14, 0x1, 0, usb, 2),
+ TEGRA124_LANE("hsic-1", 0x004, 15, 0x1, 0, usb, 2),
+ TEGRA124_LANE("pcie-0", 0x134, 16, 0x3, 1, pci, 4),
+ TEGRA124_LANE("pcie-1", 0x134, 18, 0x3, 2, pci, 4),
+ TEGRA124_LANE("pcie-2", 0x134, 20, 0x3, 3, pci, 4),
+ TEGRA124_LANE("pcie-3", 0x134, 22, 0x3, 4, pci, 4),
+ TEGRA124_LANE("pcie-4", 0x134, 24, 0x3, 5, pci, 4),
+ TEGRA124_LANE("sata-0", 0x134, 26, 0x3, 6, pci, 4),
+};
+
+static const struct tegra_xusb_padctl_soc tegra124_soc = {
+ .num_lanes = ARRAY_SIZE(tegra124_lanes),
+ .lanes = tegra124_lanes,
+};
+
+static __maybe_unused struct of_device_id pinctrl_tegra_xusb_dt_ids[] = {
+ {
+ .compatible = "nvidia,tegra124-xusb-padctl",
+ .data = (unsigned long)&tegra124_soc,
+ }, {
+ /* sentinel */
+ }
+};
+
+static struct driver_d pinctrl_tegra_xusb_driver = {
+ .name = "pinctrl-tegra-xusb",
+ .probe = pinctrl_tegra_xusb_probe,
+ .of_compatible = DRV_OF_COMPAT(pinctrl_tegra_xusb_dt_ids),
+};
+
+static int pinctrl_tegra_xusb_init(void)
+{
+ return platform_driver_register(&pinctrl_tegra_xusb_driver);
+}
+postcore_initcall(pinctrl_tegra_xusb_init);
diff --git a/drivers/pinctrl/pinctrl-tegra20.c b/drivers/pinctrl/pinctrl-tegra20.c
index 3c11be6f55..be9d8a996d 100644
--- a/drivers/pinctrl/pinctrl-tegra20.c
+++ b/drivers/pinctrl/pinctrl-tegra20.c
@@ -320,10 +320,14 @@ static int pinctrl_tegra20_probe(struct device_d *dev)
ctrl->pinctrl.ops = &pinctrl_tegra20_ops;
ret = pinctrl_register(&ctrl->pinctrl);
- if (ret)
+ if (ret) {
free(ctrl);
+ return ret;
+ }
+
+ of_pinctrl_select_state(dev->device_node, "boot");
- return ret;
+ return 0;
}
static __maybe_unused struct of_device_id pinctrl_tegra20_dt_ids[] = {
diff --git a/drivers/pinctrl/pinctrl-tegra30.c b/drivers/pinctrl/pinctrl-tegra30.c
index 82772187d5..aac67605cf 100644
--- a/drivers/pinctrl/pinctrl-tegra30.c
+++ b/drivers/pinctrl/pinctrl-tegra30.c
@@ -897,10 +897,14 @@ static int pinctrl_tegra30_probe(struct device_d *dev)
ctrl->pinctrl.ops = &pinctrl_tegra30_ops;
ret = pinctrl_register(&ctrl->pinctrl);
- if (ret)
+ if (ret) {
free(ctrl);
+ return ret;
+ }
+
+ of_pinctrl_select_state(dev->device_node, "boot");
- return ret;
+ return 0;
}
static __maybe_unused struct of_device_id pinctrl_tegra30_dt_ids[] = {
diff --git a/drivers/serial/serial_ns16550.c b/drivers/serial/serial_ns16550.c
index 53d48a06c2..8f2e93fa68 100644
--- a/drivers/serial/serial_ns16550.c
+++ b/drivers/serial/serial_ns16550.c
@@ -311,6 +311,11 @@ static __maybe_unused struct ns16550_drvdata jz_drvdata = {
.init_port = ns16550_jz_init_port,
};
+static __maybe_unused struct ns16550_drvdata tegra_drvdata = {
+ .init_port = ns16550_serial_init_port,
+ .linux_console_name = "ttyS",
+};
+
static int ns16550_init_iomem(struct device_d *dev, struct ns16550_priv *priv)
{
struct resource *res;
@@ -418,6 +423,7 @@ static int ns16550_probe(struct device_d *dev)
ret = PTR_ERR(priv->clk);
goto err;
}
+ clk_enable(priv->clk);
priv->plat.clock = clk_get_rate(priv->clk);
}
@@ -476,6 +482,12 @@ static struct of_device_id ns16550_serial_dt_ids[] = {
.data = (unsigned long)&omap_drvdata,
},
#endif
+#if IS_ENABLED(CONFIG_ARCH_TEGRA)
+ {
+ .compatible = "nvidia,tegra20-uart",
+ .data = (unsigned long)&tegra_drvdata,
+ },
+#endif
#if IS_ENABLED(CONFIG_MACH_MIPS_XBURST)
{
.compatible = "ingenic,jz4740-uart",
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 0ec1320b2f..3d0e73bf9f 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -114,8 +114,15 @@ struct pci_dev {
};
#define to_pci_dev(dev) container_of(dev, struct pci_dev, dev)
+enum {
+ PCI_BUS_RESOURCE_IO = 0,
+ PCI_BUS_RESOURCE_MEM = 1,
+ PCI_BUS_RESOURCE_MEM_PREF = 2,
+ PCI_BUS_RESOURCE_BUSN = 3,
+};
struct pci_bus {
struct pci_controller *host; /* associated host controller */
+ struct device_d *parent;
struct list_head node; /* node in list of buses */
struct list_head children; /* list of child buses */
struct list_head devices; /* list of devices on this bus */
@@ -152,10 +159,12 @@ extern struct pci_ops *pci_ops;
*/
struct pci_controller {
struct pci_controller *next;
+ struct device_d *parent;
struct pci_bus *bus;
struct pci_ops *pci_ops;
struct resource *mem_resource;
+ struct resource *mem_pref_resource;
unsigned long mem_offset;
struct resource *io_resource;
unsigned long io_offset;
diff --git a/include/linux/pci_regs.h b/include/linux/pci_regs.h
index 14a3ed3184..8669fc7393 100644
--- a/include/linux/pci_regs.h
+++ b/include/linux/pci_regs.h
@@ -107,4 +107,32 @@
#define PCI_ROM_ADDRESS_ENABLE 0x01
#define PCI_ROM_ADDRESS_MASK (~0x7ffUL)
+/* Header type 1 (PCI-to-PCI bridges) */
+#define PCI_PRIMARY_BUS 0x18 /* Primary bus number */
+#define PCI_SECONDARY_BUS 0x19 /* Secondary bus number */
+#define PCI_SUBORDINATE_BUS 0x1a /* Highest bus number behind the bridge */
+#define PCI_SEC_LATENCY_TIMER 0x1b /* Latency timer for secondary interface */
+#define PCI_IO_BASE 0x1c /* I/O range behind the bridge */
+#define PCI_IO_LIMIT 0x1d
+#define PCI_IO_RANGE_TYPE_MASK 0x0fUL /* I/O bridging type */
+#define PCI_IO_RANGE_TYPE_16 0x00
+#define PCI_IO_RANGE_TYPE_32 0x01
+#define PCI_IO_RANGE_MASK (~0x0fUL) /* Standard 4K I/O windows */
+#define PCI_IO_1K_RANGE_MASK (~0x03UL) /* Intel 1K I/O windows */
+#define PCI_SEC_STATUS 0x1e /* Secondary status register, only bit 14 used */
+#define PCI_MEMORY_BASE 0x20 /* Memory range behind */
+#define PCI_MEMORY_LIMIT 0x22
+#define PCI_MEMORY_RANGE_TYPE_MASK 0x0fUL
+#define PCI_MEMORY_RANGE_MASK (~0x0fUL)
+#define PCI_PREF_MEMORY_BASE 0x24 /* Prefetchable memory range behind */
+#define PCI_PREF_MEMORY_LIMIT 0x26
+#define PCI_PREF_RANGE_TYPE_MASK 0x0fUL
+#define PCI_PREF_RANGE_TYPE_32 0x00
+#define PCI_PREF_RANGE_TYPE_64 0x01
+#define PCI_PREF_RANGE_MASK (~0x0fUL)
+#define PCI_PREF_BASE_UPPER32 0x28 /* Upper half of prefetchable memory range */
+#define PCI_PREF_LIMIT_UPPER32 0x2c
+#define PCI_IO_BASE_UPPER16 0x30 /* Upper half of I/O addresses */
+#define PCI_IO_LIMIT_UPPER16 0x32
+
#endif /* LINUX_PCI_REGS_H */
diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h
new file mode 100644
index 0000000000..94f0044036
--- /dev/null
+++ b/include/linux/phy/phy.h
@@ -0,0 +1,240 @@
+/*
+ * phy.h -- generic phy header file
+ *
+ * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
+ *
+ * Author: Kishon Vijay Abraham I <kishon@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __DRIVERS_PHY_H
+#define __DRIVERS_PHY_H
+
+#include <linux/err.h>
+#include <of.h>
+#include <regulator.h>
+
+struct phy;
+
+/**
+ * struct phy_ops - set of function pointers for performing phy operations
+ * @init: operation to be performed for initializing phy
+ * @exit: operation to be performed while exiting
+ * @power_on: powering on the phy
+ * @power_off: powering off the phy
+ * @owner: the module owner containing the ops
+ */
+struct phy_ops {
+ int (*init)(struct phy *phy);
+ int (*exit)(struct phy *phy);
+ int (*power_on)(struct phy *phy);
+ int (*power_off)(struct phy *phy);
+};
+
+/**
+ * struct phy_attrs - represents phy attributes
+ * @bus_width: Data path width implemented by PHY
+ */
+struct phy_attrs {
+ u32 bus_width;
+};
+
+/**
+ * struct phy - represents the phy device
+ * @dev: phy device
+ * @id: id of the phy device
+ * @ops: function pointers for performing phy operations
+ * @init_data: list of PHY consumers (non-dt only)
+ * @mutex: mutex to protect phy_ops
+ * @init_count: used to protect when the PHY is used by multiple consumers
+ * @power_count: used to protect when the PHY is used by multiple consumers
+ * @phy_attrs: used to specify PHY specific attributes
+ */
+struct phy {
+ struct device_d dev;
+ int id;
+ const struct phy_ops *ops;
+ struct phy_init_data *init_data;
+ int init_count;
+ int power_count;
+ struct phy_attrs attrs;
+ struct regulator *pwr;
+};
+
+/**
+ * struct phy_provider - represents the phy provider
+ * @dev: phy provider device
+ * @owner: the module owner having of_xlate
+ * @of_xlate: function pointer to obtain phy instance from phy pointer
+ * @list: to maintain a linked list of PHY providers
+ */
+struct phy_provider {
+ struct device_d *dev;
+ struct list_head list;
+ struct phy * (*of_xlate)(struct device_d *dev,
+ struct of_phandle_args *args);
+};
+
+/**
+ * struct phy_consumer - represents the phy consumer
+ * @dev_name: the device name of the controller that will use this PHY device
+ * @port: name given to the consumer port
+ */
+struct phy_consumer {
+ const char *dev_name;
+ const char *port;
+};
+
+/**
+ * struct phy_init_data - contains the list of PHY consumers
+ * @num_consumers: number of consumers for this PHY device
+ * @consumers: list of PHY consumers
+ */
+struct phy_init_data {
+ unsigned int num_consumers;
+ struct phy_consumer *consumers;
+};
+
+#define PHY_CONSUMER(_dev_name, _port) \
+{ \
+ .dev_name = _dev_name, \
+ .port = _port, \
+}
+
+#define to_phy(dev) (container_of((dev), struct phy, dev))
+
+#define of_phy_provider_register(dev, xlate) \
+ __of_phy_provider_register((dev), (xlate))
+
+
+static inline void phy_set_drvdata(struct phy *phy, void *data)
+{
+ phy->dev.priv = data;
+}
+
+static inline void *phy_get_drvdata(struct phy *phy)
+{
+ return phy->dev.priv;
+}
+
+#if IS_ENABLED(CONFIG_GENERIC_PHY)
+int phy_init(struct phy *phy);
+int phy_exit(struct phy *phy);
+int phy_power_on(struct phy *phy);
+int phy_power_off(struct phy *phy);
+static inline int phy_get_bus_width(struct phy *phy)
+{
+ return phy->attrs.bus_width;
+}
+static inline void phy_set_bus_width(struct phy *phy, int bus_width)
+{
+ phy->attrs.bus_width = bus_width;
+}
+struct phy *phy_get(struct device_d *dev, const char *string);
+struct phy *phy_optional_get(struct device_d *dev, const char *string);
+void phy_put(struct phy *phy);
+struct phy *of_phy_get(struct device_node *np, const char *con_id);
+struct phy *of_phy_simple_xlate(struct device_d *dev,
+ struct of_phandle_args *args);
+struct phy *phy_create(struct device_d *dev, struct device_node *node,
+ const struct phy_ops *ops,
+ struct phy_init_data *init_data);
+void phy_destroy(struct phy *phy);
+struct phy_provider *__of_phy_provider_register(struct device_d *dev,
+ struct phy * (*of_xlate)(struct device_d *dev,
+ struct of_phandle_args *args));
+void of_phy_provider_unregister(struct phy_provider *phy_provider);
+#else
+static inline int phy_init(struct phy *phy)
+{
+ if (!phy)
+ return 0;
+ return -ENOSYS;
+}
+
+static inline int phy_exit(struct phy *phy)
+{
+ if (!phy)
+ return 0;
+ return -ENOSYS;
+}
+
+static inline int phy_power_on(struct phy *phy)
+{
+ if (!phy)
+ return 0;
+ return -ENOSYS;
+}
+
+static inline int phy_power_off(struct phy *phy)
+{
+ if (!phy)
+ return 0;
+ return -ENOSYS;
+}
+
+static inline int phy_get_bus_width(struct phy *phy)
+{
+ return -ENOSYS;
+}
+
+static inline void phy_set_bus_width(struct phy *phy, int bus_width)
+{
+ return;
+}
+
+static inline struct phy *phy_get(struct device_d *dev, const char *string)
+{
+ return ERR_PTR(-ENOSYS);
+}
+
+static inline struct phy *phy_optional_get(struct device_d *dev,
+ const char *string)
+{
+ return ERR_PTR(-ENOSYS);
+}
+
+static inline void phy_put(struct phy *phy)
+{
+}
+
+static inline struct phy *of_phy_get(struct device_node *np, const char *con_id)
+{
+ return ERR_PTR(-ENOSYS);
+}
+
+static inline struct phy *of_phy_simple_xlate(struct device_d *dev,
+ struct of_phandle_args *args)
+{
+ return ERR_PTR(-ENOSYS);
+}
+
+static inline struct phy *phy_create(struct device_d *dev,
+ struct device_node *node,
+ const struct phy_ops *ops,
+ struct phy_init_data *init_data)
+{
+ return ERR_PTR(-ENOSYS);
+}
+
+static inline void phy_destroy(struct phy *phy)
+{
+}
+
+static inline struct phy_provider *__of_phy_provider_register(
+ struct device_d *dev, struct phy * (*of_xlate)(
+ struct device_d *dev, struct of_phandle_args *args))
+{
+ return ERR_PTR(-ENOSYS);
+}
+
+static inline void of_phy_provider_unregister(struct phy_provider *phy_provider)
+{
+}
+#endif
+
+#endif /* __DRIVERS_PHY_H */
diff --git a/include/of_address.h b/include/of_address.h
index 9022ab7ca0..ebf3ec2a24 100644
--- a/include/of_address.h
+++ b/include/of_address.h
@@ -4,6 +4,38 @@
#include <common.h>
#include <of.h>
+struct of_pci_range_parser {
+ struct device_node *node;
+ const __be32 *range;
+ const __be32 *end;
+ int np;
+ int pna;
+};
+
+struct of_pci_range {
+ u32 pci_space;
+ u64 pci_addr;
+ u64 cpu_addr;
+ u64 size;
+ u32 flags;
+};
+
+#define for_each_of_pci_range(parser, range) \
+ for (; of_pci_range_parser_one(parser, range);)
+
+static inline void of_pci_range_to_resource(struct of_pci_range *range,
+ struct device_node *np,
+ struct resource *res)
+{
+ res->flags = range->flags;
+ res->start = range->cpu_addr;
+ res->end = range->cpu_addr + range->size - 1;
+ res->parent = NULL;
+ INIT_LIST_HEAD(&res->children);
+ INIT_LIST_HEAD(&res->sibling);
+ res->name = np->full_name;
+}
+
#ifndef pci_address_to_pio
static inline unsigned long pci_address_to_pio(phys_addr_t addr) { return -1; }
#endif
@@ -69,4 +101,29 @@ static inline void __iomem *of_iomap(struct device_node *np, int index)
#endif /* CONFIG_OFTREE */
+#ifdef CONFIG_OF_PCI
+
+extern int of_pci_range_parser_init(struct of_pci_range_parser *parser,
+ struct device_node *node);
+
+extern struct of_pci_range *of_pci_range_parser_one(
+ struct of_pci_range_parser *parser,
+ struct of_pci_range *range);
+
+#else
+
+static inline int of_pci_range_parser_init(struct of_pci_range_parser *parser,
+ struct device_node *node)
+{
+ return -1;
+}
+
+static inline struct of_pci_range *of_pci_range_parser_one(
+ struct of_pci_range_parser *parser,
+ struct of_pci_range *range)
+{
+ return NULL;
+}
+#endif /* CONFIG_OF_PCI */
+
#endif /* __OF_ADDRESS_H */
diff --git a/include/reset_source.h b/include/reset_source.h
index bff7f97850..6620228722 100644
--- a/include/reset_source.h
+++ b/include/reset_source.h
@@ -20,6 +20,7 @@ enum reset_src_type {
RESET_WDG, /* watchdog */
RESET_WKE, /* wake-up (some SoCs can handle this) */
RESET_JTAG, /* JTAG reset */
+ RESET_THERM, /* SoC shut down because of overtemperature */
};
#ifdef CONFIG_RESET_SOURCE