diff options
author | Eric Yuen <eyuen@nvidia.com> | 2014-07-08 10:34:33 +0000 |
---|---|---|
committer | Marcel Ziswiler <marcel.ziswiler@toradex.com> | 2014-07-16 17:22:42 +0200 |
commit | ff09771639a39c834f364a75faa49bc44bac901e (patch) | |
tree | 28a36c5422b02541b6b9be2fc88d73ca88527c61 /arch/arm/mach-tegra | |
parent | 491f263ebfb338c59abfbde6d4e0e7256a0150fa (diff) |
arm: tegra3: PCIe Clock and Reset Conform to Specification
PCIe Reset line must be asserted for at least 100us after clock is enabled.
PEX 2 Controller Register fix, offsets are not at constant intervals.
Bug 1521306
Reviewed-on: http://git-master/r/225399
(cherry picked from commit df0760bf515236bed2e87e590509642ab72a01b5)
Change-Id: I7b44ea51e7e02f2bca93cfc75ed85e01ab91fe03
Signed-off-by: Shreshtha Sahu <ssahu@nvidia.com>
Diffstat (limited to 'arch/arm/mach-tegra')
-rw-r--r-- | arch/arm/mach-tegra/pcie.c | 33 |
1 files changed, 26 insertions, 7 deletions
diff --git a/arch/arm/mach-tegra/pcie.c b/arch/arm/mach-tegra/pcie.c index ee26138a6e61..7765e56c6d39 100644 --- a/arch/arm/mach-tegra/pcie.c +++ b/arch/arm/mach-tegra/pcie.c @@ -342,6 +342,15 @@ static bool is_dock_conn_at_boot = true; void __iomem *tegra_pcie_io_base; EXPORT_SYMBOL(tegra_pcie_io_base); +/* Array of PCIe Controller Register offsets */ +static u32 pex_controller_registers[] = { + AFI_PEX0_CTRL, + AFI_PEX1_CTRL, +#if MAX_PCIE_SUPPORTED_PORTS == 3 + AFI_PEX2_CTRL, +#endif +}; + static inline void afi_writel(u32 value, unsigned long offset) { writel(value, offset + AFI_OFFSET + tegra_pcie.regs); @@ -797,15 +806,13 @@ static void tegra_pcie_enable_controller(void) reg |= 1 << MSELECT_CONFIG_0_ENABLE_PCIE_APERTURE; writel(reg, reg_mselect_base); - /* Enable slot clock and pulse the reset signals */ - for (i = 0, reg = AFI_PEX0_CTRL; i < MAX_PCIE_SUPPORTED_PORTS; - i++, reg += (i*8)) { - val = afi_readl(reg) | AFI_PEX_CTRL_CLKREQ_EN | AFI_PEX_CTRL_REFCLK_EN; - afi_writel(val, reg); + /* Enable slot clock and ensure reset signals is assert */ + for (i = 0; i < ARRAY_SIZE(pex_controller_registers); i++) { + reg = pex_controller_registers[i]; + val = afi_readl(reg) | AFI_PEX_CTRL_REFCLK_EN | + AFI_PEX_CTRL_CLKREQ_EN; val &= ~AFI_PEX_CTRL_RST; - afi_writel(val, reg); - val = afi_readl(reg) | AFI_PEX_CTRL_RST; afi_writel(val, reg); } afi_writel(0, AFI_PEXBIAS_CTRL_0); @@ -865,6 +872,18 @@ static void tegra_pcie_enable_controller(void) val = pads_readl(PADS_PLL_CTL); } while (!(val & PADS_PLL_CTL_LOCKDET)); + /* Wait for clock to latch (min of 100us) */ + udelay(100); + + /* deassert PEX reset signal */ + for (i = 0; i < ARRAY_SIZE(pex_controller_registers); i++) { + reg = pex_controller_registers[i]; + val = afi_readl(reg); + val |= AFI_PEX_CTRL_RST; + afi_writel(val, reg); + } + + /* turn off IDDQ override */ val = pads_readl(PADS_CTL) & ~PADS_CTL_IDDQ_1L; pads_writel(val, PADS_CTL); |