summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra
diff options
context:
space:
mode:
authorEric Yuen <eyuen@nvidia.com>2014-07-08 10:34:33 +0000
committerMarcel Ziswiler <marcel.ziswiler@toradex.com>2014-07-16 17:22:42 +0200
commitff09771639a39c834f364a75faa49bc44bac901e (patch)
tree28a36c5422b02541b6b9be2fc88d73ca88527c61 /arch/arm/mach-tegra
parent491f263ebfb338c59abfbde6d4e0e7256a0150fa (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.c33
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);