[U-Boot] [PATCH 23/23] ARM: tegra: Enable PCIe on Jetson TK1

Thierry Reding
2014-08-18T07:16:36Z

From: Thierry Reding <treding@nvidia.com>

The Jetson TK1 has an ethernet NIC connected to the PCIe bus and routes
the second root port to a miniPCIe slot. Enable the PCIe controller and
the network driver to allow the device to boot over the network.

Signed-off-by: Thierry Reding <treding@nvidia.com>
---
arch/arm/dts/tegra124-jetson-tk1.dts | 347 +++++++++++++++++++++++++++++++++++
board/nvidia/jetson-tk1/jetson-tk1.c | 218 ++++++++++++++++++++++
include/configs/jetson-tk1.h | 10 +
3 files changed, 575 insertions(+)

diff --git a/arch/arm/dts/tegra124-jetson-tk1.dts b/arch/arm/dts/tegra124-jetson-tk1.dts
index f61736f0ef0f..f594644de74e 100644
--- a/arch/arm/dts/tegra124-jetson-tk1.dts
+++ b/arch/arm/dts/tegra124-jetson-tk1.dts
@@ -26,6 +26,26 @@
reg = <0x80000000 0x80000000>;
};

+ pcie-controller at 01003000 {
+ status = "okay";
+
+ avddio-pex-supply = <&vdd_1v05_run>;
+ vddio-pex-supply = <&vdd_1v05_run>;
+ avdd-pex-pll-supply = <&vdd_1v05_run>;
+ hvdd-pex-supply = <&vdd_3v3_lp0>;
+ hvdd-pex-plle-supply = <&vdd_3v3_lp0>;
+ vddio-pex-ctl-supply = <&vdd_3v3_lp0>;
+ avdd-plle-supply = <&avdd_1v05_run>;
+
+ pci at 1,0 {
+ status = "okay";
+ };
+
+ pci at 2,0 {
+ status = "okay";
+ };
+ };
+
i2c at 7000c000 {
status = "okay";
clock-frequency = <100000>;
@@ -46,9 +66,195 @@
clock-frequency = <100000>;
};

+ /* Expansion PWR_I2C_*, on-board components */
i2c at 7000d000 {
status = "okay";
clock-frequency = <400000>;
+
+ pmic: pmic at 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,ext-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,ext-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;
+ };
+
+ vdd_gpu: 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;
+ };
+
+ avdd_1v05_run: ldo0 {
+ regulator-name = "+1.05V_RUN_AVDD";
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1050000>;
+ regulator-boot-on;
+ regulator-always-on;
+ ams,ext-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>;
+ };
+
+ ldo11 {
+ regulator-name = "+1.8V_RUN_VPP_FUSE";
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <1800000>;
+ };
+ };
+ };
};

i2c at 7000d100 {
@@ -114,4 +320,145 @@
status = "okay";
nvidia,vbus-gpio = <&gpio 109 0>; /* gpio PN5, USB_VBUS_EN1 */
};
+
+ regulators {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ vdd_mux: regulator at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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 at 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>;
+ };
+
+ /* Molex power connector */
+ vdd_5v0_sata: regulator at 13 {
+ compatible = "regulator-fixed";
+ reg = <13>;
+ regulator-name = "+5V_SATA";
+ regulator-min-microvolt = <5000000>;
+ regulator-max-microvolt = <5000000>;
+ gpio = <&gpio TEGRA_GPIO(EE, 2) GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ vin-supply = <&vdd_5v0_sys>;
+ };
+
+ vdd_12v0_sata: regulator at 14 {
+ compatible = "regulator-fixed";
+ reg = <14>;
+ regulator-name = "+12V_SATA";
+ regulator-min-microvolt = <12000000>;
+ regulator-max-microvolt = <12000000>;
+ gpio = <&gpio TEGRA_GPIO(EE, 2) GPIO_ACTIVE_HIGH>;
+ enable-active-high;
+ vin-supply = <&vdd_mux>;
+ };
+ };
};
diff --git a/board/nvidia/jetson-tk1/jetson-tk1.c b/board/nvidia/jetson-tk1/jetson-tk1.c
index 5d37718f3b89..c1deaa11d63e 100644
--- a/board/nvidia/jetson-tk1/jetson-tk1.c
+++ b/board/nvidia/jetson-tk1/jetson-tk1.c
@@ -6,9 +6,25 @@
*/

#include <common.h>
+#include <errno.h>
#include <asm/arch/gpio.h>
#include <asm/arch/pinmux.h>
#include "pinmux-config-jetson-tk1.h"
+#include <i2c.h>
+#include <netdev.h>
+
+#define PMU_I2C_ADDRESS 0x40
+#define AS3722_DEVICE_ID 0x0c
+
+#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_CONTROL_MODE_OUTPUT_VDDL (7 << 0)
+#define AS3722_GPIO_CONTROL_INVERT (1 << 7)
+#define AS3722_GPIO_SIGNAL_OUT 0x20
+#define AS3722_SD_CONTROL 0x4d
+#define AS3722_ASIC_ID1 0x90
+#define AS3722_ASIC_ID2 0x91

/*
* Routine: pinmux_init
@@ -27,3 +43,205 @@ void pinmux_init(void)
pinmux_config_drvgrp_table(jetson_tk1_drvgrps,
ARRAY_SIZE(jetson_tk1_drvgrps));
}
+
+#ifdef CONFIG_PCI_TEGRA
+static int as3722_read(u8 reg, u8 *value)
+{
+ int err;
+
+ err = i2c_read(PMU_I2C_ADDRESS, reg, 1, value, 1);
+ if (err < 0)
+ return err;
+
+ return 0;
+}
+
+static int as3722_write(u8 reg, u8 value)
+{
+ int err;
+
+ err = i2c_write(PMU_I2C_ADDRESS, reg, 1, &value, 1);
+ if (err < 0)
+ return err;
+
+ return 0;
+}
+
+static int as3722_read_id(u8 *id, u8 *revision)
+{
+ int err;
+
+ err = as3722_read(AS3722_ASIC_ID1, id);
+ if (err) {
+ error("as3722: failed to read ID1 register: %d\n", err);
+ return err;
+ }
+
+ err = as3722_read(AS3722_ASIC_ID2, revision);
+ if (err) {
+ error("as3722: failed to read ID2 register: %d\n", err);
+ return err;
+ }
+
+ return 0;
+}
+
+static int as3722_sd_enable(u8 sd)
+{
+ u8 value;
+ int err;
+
+ err = as3722_read(AS3722_SD_CONTROL, &value);
+ if (err) {
+ error("as3722: failed to read SD control register: %d\n", err);
+ return err;
+ }
+
+ value |= 1 << sd;
+
+ err = as3722_write(AS3722_SD_CONTROL, value);
+ if (err < 0) {
+ error("as3722: failed to write SD control register: %d\n", err);
+ return err;
+ }
+
+ return 0;
+}
+
+static int as3722_sd_set_voltage(u8 sd, u8 value)
+{
+ int err;
+
+ if (sd > 6)
+ return -EINVAL;
+
+ err = as3722_write(AS3722_SD_VOLTAGE(sd), value);
+ if (err < 0) {
+ error("as3722: failed to write SD%u voltage register: %d\n", sd, err);
+ return err;
+ }
+
+ return 0;
+}
+
+static int as3722_gpio_set(u8 gpio, u8 level)
+{
+ u8 value;
+ int err;
+
+ if (gpio > 7)
+ return -EINVAL;
+
+ err = as3722_read(AS3722_GPIO_SIGNAL_OUT, &value);
+ if (err < 0) {
+ error("as3722: failed to read GPIO signal out register: %d\n",
+ err);
+ return err;
+ }
+
+ if (level == 0)
+ value &= ~(1 << gpio);
+ else
+ value |= 1 << gpio;
+
+ err = as3722_write(AS3722_GPIO_SIGNAL_OUT, value);
+ if (err) {
+ error("as3722: failed to set GPIO#%u %s: %d\n", gpio,
+ (level == 0) ? "low" : "high", err);
+ return err;
+ }
+
+ return 0;
+}
+
+static int as3722_gpio_direction_output(u8 gpio, u8 level)
+{
+ u8 value;
+ int err;
+
+ if (gpio > 7)
+ return -EINVAL;
+
+ if (level == 0)
+ value = AS3722_GPIO_CONTROL_MODE_OUTPUT_VDDL;
+ else
+ value = AS3722_GPIO_CONTROL_MODE_OUTPUT_VDDH;
+
+ err = as3722_write(AS3722_GPIO_CONTROL(gpio), value);
+ if (err) {
+ error("as3722: failed to configure GPIO#%u as output: %d\n",
+ gpio, err);
+ return err;
+ }
+
+ err = as3722_gpio_set(gpio, level);
+ if (err < 0) {
+ error("as3722: failed to set GPIO#%u high: %d\n", gpio, err);
+ return err;
+ }
+
+ return 0;
+}
+
+int tegra_pcie_board_init(void)
+{
+ u8 id, revision, value;
+ unsigned int old_bus;
+ int err;
+
+ old_bus = i2c_get_bus_num();
+
+ err = i2c_set_bus_num(0);
+ if (err) {
+ error("failed to set I2C bus\n");
+ return err;
+ }
+
+ err = as3722_read_id(&id, &revision);
+ if (err < 0) {
+ error("as3722: failed to read ID: %d\n", err);
+ return err;
+ }
+
+ if (id != AS3722_DEVICE_ID) {
+ error("as3722: PMIC is not an AS3722\n");
+ return -ENODEV;
+ }
+
+ err = as3722_sd_enable(4);
+ if (err < 0) {
+ error("as3722: failed to enable SD4: %d\n", err);
+ return err;
+ }
+
+ err = as3722_sd_set_voltage(4, 0x24);
+ if (err < 0) {
+ error("as3722: failed to set SD4 voltage: %d\n", err);
+ return err;
+ }
+
+ value = AS3722_GPIO_CONTROL_MODE_OUTPUT_VDDH |
+ AS3722_GPIO_CONTROL_INVERT;
+
+ err = as3722_write(AS3722_GPIO_CONTROL(1), value);
+ if (err) {
+ error("as3722: failed to configure GPIO#1 as output: %d\n", err);
+ return err;
+ }
+
+ err = as3722_gpio_direction_output(2, 1);
+ if (err < 0) {
+ error("as3722: failed to set GPIO#2 high: %d\n", err);
+ return err;
+ }
+
+ i2c_set_bus_num(old_bus);
+
+ return 0;
+}
+
+int board_eth_init(bd_t *bis)
+{
+ return pci_eth_init(bis);
+}
+#endif /* PCI */
diff --git a/include/configs/jetson-tk1.h b/include/configs/jetson-tk1.h
index 0b9e5b699fa6..b0393509681c 100644
--- a/include/configs/jetson-tk1.h
+++ b/include/configs/jetson-tk1.h
@@ -71,6 +71,16 @@
#define CONFIG_USB_HOST_ETHER
#define CONFIG_USB_ETHER_ASIX

+/* PCI host support */
+#define CONFIG_PCI
+#define CONFIG_PCI_TEGRA
+#define CONFIG_PCI_PNP
+#define CONFIG_CMD_PCI
+#define CONFIG_CMD_PCI_ENUM
+
+/* PCI networking support */
+#define CONFIG_RTL8169
+
/* General networking support */
#define CONFIG_CMD_NET
#define CONFIG_CMD_DHCP
--
2.0.4