summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/boot/dts/tegra124-platforms/tegra124-apalis-gpio.dtsi9
-rw-r--r--arch/arm/boot/dts/tegra124-platforms/tegra124-apalis-pmic.dtsi16
-rw-r--r--arch/arm/mach-tegra/board-apalis-tk1.h4
-rw-r--r--drivers/pci/host/pci-tegra.c149
4 files changed, 135 insertions, 43 deletions
diff --git a/arch/arm/boot/dts/tegra124-platforms/tegra124-apalis-gpio.dtsi b/arch/arm/boot/dts/tegra124-platforms/tegra124-apalis-gpio.dtsi
index 100e3449c9b0..3dc15c51114b 100644
--- a/arch/arm/boot/dts/tegra124-platforms/tegra124-apalis-gpio.dtsi
+++ b/arch/arm/boot/dts/tegra124-platforms/tegra124-apalis-gpio.dtsi
@@ -36,6 +36,8 @@
>;
gpio-output-low = <
TEGRA_GPIO(C, 0)
+ TEGRA_GPIO(O, 5) /* LAN_WAKE_N */
+ TEGRA_GPIO(O, 6) /* LAN_DEV_OFF_N */
TEGRA_GPIO(Q, 0) /* Shift_CTRL_OE[0] */
TEGRA_GPIO(Q, 1) /* Shift_CTRL_OE[1] */
TEGRA_GPIO(Q, 2) /* Shift_CTRL_OE[2] */
@@ -43,7 +45,9 @@
TEGRA_GPIO(R, 0) /* Shift_CTRL_Dir_In[0] */
TEGRA_GPIO(R, 1) /* Shift_CTRL_Dir_In[1] */
TEGRA_GPIO(R, 2) /* Shift_CTRL_OE[3] */
+ TEGRA_GPIO(S, 2) /* LAN_RESET_N */
TEGRA_GPIO(S, 3) /* Shift_CTRL_Dir_In[2] */
+ TEGRA_GPIO(U, 4) /* RESET_MOCI_CTRL */
TEGRA_GPIO(BB, 3)
TEGRA_GPIO(BB, 6)
>;
@@ -51,14 +55,9 @@
TEGRA_GPIO(N, 2)
TEGRA_GPIO(N, 4)
TEGRA_GPIO(N, 5)
-#if 0
- TEGRA_GPIO(O, 6) /* LAN_DEV_OFF# */
-#endif
TEGRA_GPIO(Q, 5) /* Shift_CTRL_Dir_Out[0] */
TEGRA_GPIO(Q, 6) /* Shift_CTRL_Dir_Out[1] */
TEGRA_GPIO(Q, 7) /* Shift_CTRL_Dir_Out[2] */
- TEGRA_GPIO(S, 2) /* LAN_RESET# */
- TEGRA_GPIO(U, 4)
TEGRA_GPIO(BB, 5)
>;
};
diff --git a/arch/arm/boot/dts/tegra124-platforms/tegra124-apalis-pmic.dtsi b/arch/arm/boot/dts/tegra124-platforms/tegra124-apalis-pmic.dtsi
index 695891d28a80..342487b285f0 100644
--- a/arch/arm/boot/dts/tegra124-platforms/tegra124-apalis-pmic.dtsi
+++ b/arch/arm/boot/dts/tegra124-platforms/tegra124-apalis-pmic.dtsi
@@ -460,14 +460,26 @@
regulator-name = "+V3.3_ETH(ldo9)";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
- regulator-always-on;
+
+ consumers {
+ c1 {
+ regulator-consumer-supply = "i210_vdd3p3_ldo9";
+ regulator-consumer-device = "pcie-controller.1";
+ };
+ };
};
as3722_ldo10: ldo10 {
regulator-name = "+V3.3_ETH(ldo10)";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
- regulator-always-on;
+
+ consumers {
+ c1 {
+ regulator-consumer-supply = "i210_vdd3p3_ldo10";
+ regulator-consumer-device = "pcie-controller.1";
+ };
+ };
};
as3722_ldo11: ldo11 {
diff --git a/arch/arm/mach-tegra/board-apalis-tk1.h b/arch/arm/mach-tegra/board-apalis-tk1.h
index b825abb0bdb2..d6114a1af820 100644
--- a/arch/arm/mach-tegra/board-apalis-tk1.h
+++ b/arch/arm/mach-tegra/board-apalis-tk1.h
@@ -60,7 +60,9 @@
#define I2C3_SCL TEGRA_GPIO_PBB1
#define I2C3_SDA TEGRA_GPIO_PBB2
+#define LAN_DEV_OFF_N TEGRA_GPIO_PO6
#define LAN_RESET_N TEGRA_GPIO_PS2
+#define LAN_WAKE_N TEGRA_GPIO_PO5
#define MMC1_CD_N TEGRA_GPIO_PV3
@@ -69,7 +71,7 @@
#define PWR_I2C_SCL TEGRA_GPIO_PZ6
#define PWR_I2C_SDA TEGRA_GPIO_PZ7
-#define RESET_MOCI_N TEGRA_GPIO_PU4
+#define RESET_MOCI_CTRL TEGRA_GPIO_PU4
#define SATA1_ACT_N TEGRA_GPIO_PN2
diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c
index 1ef5791a892b..e0e7998f57f3 100644
--- a/drivers/pci/host/pci-tegra.c
+++ b/drivers/pci/host/pci-tegra.c
@@ -282,6 +282,10 @@ struct tegra_pcie_info {
struct regulator *regulator_hvdd;
struct regulator *regulator_pexio;
struct regulator *regulator_avdd_plle;
+#ifdef CONFIG_MACH_APALIS_TK1
+ struct regulator *regulator_apalis_tk1_ldo9;
+ struct regulator *regulator_apalis_tk1_ldo10;
+#endif /* CONFIG_MACH_APALIS_TK1 */
struct clk *pcie_xclk;
struct clk *pcie_mselect;
struct clk *pcie_emc;
@@ -976,25 +980,87 @@ static int tegra_pcie_enable_pads(bool enable)
return err;
}
-static int tegra_pcie_enable_controller(void)
+static void tegra_pcie_port_reset(struct tegra_pcie_port *pp, u32 reset_reg)
{
- u32 val, reg;
- int i, ret = 0, lane_owner;
+ u32 reg;
PR_FUNC_LINE;
-
#ifdef CONFIG_MACH_APALIS_TK1
/* Reset PLX PEX 8605 PCIe Switch plus PCIe devices on Apalis Evaluation
Board */
- if (g_pex_perst) gpio_request(PEX_PERST_N, "PEX_PERST_N");
- gpio_request(RESET_MOCI_N, "RESET_MOCI_N");
if (g_pex_perst) gpio_direction_output(PEX_PERST_N, 0);
- gpio_direction_output(RESET_MOCI_N, 0);
+ gpio_direction_output(RESET_MOCI_CTRL, 0);
/* Reset I210 Gigabit Ethernet Controller */
- gpio_request(LAN_RESET_N, "LAN_RESET_N");
gpio_direction_output(LAN_RESET_N, 0);
+
+ /*
+ * Make sure we don't get any back feeding from LAN_WAKE_N resp.
+ * DEV_OFF_N
+ */
+ gpio_direction_output(LAN_WAKE_N, 0);
+ gpio_direction_output(LAN_DEV_OFF_N, 0);
+
+ /* Make sure LDO9 and LDO10 are initially disabled @ 0V */
+ if (regulator_is_enabled(tegra_pcie.regulator_apalis_tk1_ldo9))
+ regulator_disable(tegra_pcie.regulator_apalis_tk1_ldo9);
+ if (regulator_is_enabled(tegra_pcie.regulator_apalis_tk1_ldo10))
+ regulator_disable(tegra_pcie.regulator_apalis_tk1_ldo10);
+
+ mdelay(100);
+
+ /* Make sure LAN_WAKE_N gets re-configured as a GPIO input */
+ gpio_direction_input(LAN_WAKE_N);
+
+ /* Make sure controller gets enabled by disabling DEV_OFF_N */
+ gpio_set_value(LAN_DEV_OFF_N, 1);
+
+ /*
+ * Enable LDO9 and LDO10 for +V3.3_ETH on patched prototype
+ * V1.0A and sample V1.0B and newer modules
+ */
+ if (regulator_enable(tegra_pcie.regulator_apalis_tk1_ldo9) < 0) {
+ pr_err("pcie: couldn't enable regulator i210_vdd3p3_ldo9\n");
+ return;
+ }
+ if (regulator_enable(tegra_pcie.regulator_apalis_tk1_ldo10) < 0) {
+ pr_err("pcie: couldn't enable regulator i210_vdd3p3_ldo10\n");
+ return;
+ }
+#endif /* CONFIG_MACH_APALIS_TK1 */
+
+ /* Pulse the PEX reset */
+ reg = afi_readl(reset_reg) & ~AFI_PEX_CTRL_RST;
+ afi_writel(reg, reset_reg);
+
+ /* Must be asserted for 100 ms after power and clocks are stable */
+ mdelay(100);
+
+ reg = afi_readl(reset_reg) | AFI_PEX_CTRL_RST;
+ afi_writel(reg, reset_reg);
+
+#ifdef CONFIG_MACH_APALIS_TK1
+ gpio_set_value(LAN_RESET_N, 1);
+
+ if (g_pex_perst) gpio_set_value(PEX_PERST_N, 1);
+ /* Err_5: PEX_REFCLK_OUTpx/nx Clock Outputs is not Guaranteed Until
+ 900 us After PEX_PERST# De-assertion */
+ if (g_pex_perst) mdelay(1);
+ gpio_set_value(RESET_MOCI_CTRL, 1);
+
+ /* Release I210 Gigabit Ethernet Controller Reset */
+ gpio_set_value(LAN_RESET_N, 1);
#endif /* CONFIG_MACH_APALIS_TK1 */
+}
+
+static int tegra_pcie_enable_controller(void)
+{
+ u32 val, reg;
+ int i, ret = 0, lane_owner;
+ struct tegra_pcie_port *pp;
+ int ctrl_offset = AFI_PEX0_CTRL;
+
+ PR_FUNC_LINE;
/* Enable slot clock and ensure reset signal is assert */
for (i = 0; i < ARRAY_SIZE(pex_controller_registers); i++) {
@@ -1071,25 +1137,12 @@ static int tegra_pcie_enable_controller(void)
/* Wait for clock to latch (min of 100us) */
udelay(100);
- /* deassert PEX reset signal */
- for (i = 0; i < ARRAY_SIZE(pex_controller_registers); i++) {
- val = afi_readl(pex_controller_registers[i]);
- val |= AFI_PEX_CTRL_RST;
- afi_writel(val, pex_controller_registers[i]);
+ pp = tegra_pcie.port + tegra_pcie.num_ports;
+ for (i = 0; i < MAX_PCIE_SUPPORTED_PORTS; i++) {
+ ctrl_offset += (i * 8);
+ tegra_pcie_port_reset(pp, ctrl_offset);
}
-#ifdef CONFIG_MACH_APALIS_TK1
- /* Must be asserted for 100 ms after power and clocks are stable */
- if (g_pex_perst) gpio_set_value(PEX_PERST_N, 1);
- /* Err_5: PEX_REFCLK_OUTpx/nx Clock Outputs is not Guaranteed Until
- 900 us After PEX_PERST# De-assertion */
- if (g_pex_perst) mdelay(1);
- gpio_set_value(RESET_MOCI_N, 1);
-
- /* Release I210 Gigabit Ethernet Controller Reset */
- gpio_set_value(LAN_RESET_N, 1);
-#endif /* CONFIG_MACH_APALIS_TK1 */
-
return ret;
}
@@ -1138,12 +1191,37 @@ static int tegra_pcie_enable_regulators(void)
tegra_pcie.regulator_avdd_plle = 0;
}
}
+
+#ifdef CONFIG_MACH_APALIS_TK1
+ if (tegra_pcie.regulator_apalis_tk1_ldo9 == NULL) {
+ tegra_pcie.regulator_apalis_tk1_ldo9 = regulator_get(tegra_pcie.dev, "i210_vdd3p3_ldo9");
+ if (IS_ERR(tegra_pcie.regulator_apalis_tk1_ldo9)) {
+ pr_err("pcie: couldn't get regulator i210_vdd3p3_ldo9\n");
+ tegra_pcie.regulator_apalis_tk1_ldo9 = 0;
+ }
+ }
+
+ if (tegra_pcie.regulator_apalis_tk1_ldo10 == NULL) {
+ tegra_pcie.regulator_apalis_tk1_ldo10 = regulator_get(tegra_pcie.dev, "i210_vdd3p3_ldo10");
+ if (IS_ERR(tegra_pcie.regulator_apalis_tk1_ldo10)) {
+ pr_err("pcie: couldn't get regulator i210_vdd3p3_ldo10\n");
+ tegra_pcie.regulator_apalis_tk1_ldo10 = 0;
+ }
+ }
+#endif /* CONFIG_MACH_APALIS_TK1 */
+
if (tegra_pcie.regulator_hvdd)
ret = regulator_enable(tegra_pcie.regulator_hvdd);
if (tegra_pcie.regulator_pexio)
ret = regulator_enable(tegra_pcie.regulator_pexio);
if (tegra_pcie.regulator_avdd_plle)
ret = regulator_enable(tegra_pcie.regulator_avdd_plle);
+#ifdef CONFIG_MACH_APALIS_TK1
+ if (tegra_pcie.regulator_apalis_tk1_ldo9)
+ ret = regulator_enable(tegra_pcie.regulator_apalis_tk1_ldo9);
+ if (tegra_pcie.regulator_apalis_tk1_ldo10)
+ ret = regulator_enable(tegra_pcie.regulator_apalis_tk1_ldo10);
+#endif /* CONFIG_MACH_APALIS_TK1 */
return 0;
}
@@ -1506,16 +1584,8 @@ static bool tegra_pcie_check_link(struct tegra_pcie_port *pp, int idx,
}
retry:
- if (--retries) {
- /* Pulse the PEX reset */
-/* TBD: timing not as per PCIe spec */
- reg = afi_readl(reset_reg) & ~AFI_PEX_CTRL_RST;
- afi_writel(reg, reset_reg);
- reg = afi_readl(reset_reg) | AFI_PEX_CTRL_RST;
- afi_writel(reg, reset_reg);
- }
-
- } while (retries);
+ tegra_pcie_port_reset(pp, reset_reg);
+ } while (--retries);
return false;
}
@@ -1943,6 +2013,15 @@ static int __init tegra_pcie_init(void)
tegra_pcie_power_off(false);
return err;
}
+
+#ifdef CONFIG_MACH_APALIS_TK1
+ gpio_request(LAN_DEV_OFF_N, "LAN_DEV_OFF_N");
+ gpio_request(LAN_RESET_N, "LAN_RESET_N");
+ gpio_request(LAN_WAKE_N, "LAN_WAKE_N");
+ if (g_pex_perst) gpio_request(PEX_PERST_N, "PEX_PERST_N");
+ gpio_request(RESET_MOCI_CTRL, "RESET_MOCI_CTRL");
+#endif /* CONFIG_MACH_APALIS_TK1 */
+
err = tegra_pcie_enable_controller();
if (err) {
pr_err("PCIE: enable controller failed\n");