diff options
-rw-r--r-- | arch/arm/boot/dts/tegra124-platforms/tegra124-apalis-gpio.dtsi | 9 | ||||
-rw-r--r-- | arch/arm/boot/dts/tegra124-platforms/tegra124-apalis-pmic.dtsi | 16 | ||||
-rw-r--r-- | arch/arm/mach-tegra/board-apalis-tk1.h | 4 | ||||
-rw-r--r-- | drivers/pci/host/pci-tegra.c | 149 |
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"); |