arm: tegra: PCIe Clock and Reset Conform to Spec
sreenivasulu velpula [Tue, 27 Aug 2013 05:37:40 +0000 (10:37 +0530)]
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 1228219

Change-Id: I79d354a9cf25144a8109d7d84e01b28c09017563
Signed-off-by: sreenivasulu velpula <svelpula@nvidia.com>
Reviewed-on: http://git-master/r/227450
(cherry picked from commit 17075e925e7cc708cb9748e17966995b98ccc9c3)
Reviewed-on: http://git-master/r/266430
Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com>
Tested-by: Laxman Dewangan <ldewangan@nvidia.com>

arch/arm/mach-tegra/pcie.c

index a720df2..0254098 100644 (file)
@@ -388,6 +388,15 @@ static inline u32 afi_readl(unsigned long offset)
        return readl(offset + AFI_OFFSET + tegra_pcie.regs);
 }
 
+/* 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 pads_writel(u32 value, unsigned long offset)
 {
        writel(value, offset + PADS_OFFSET + tegra_pcie.regs);
@@ -997,15 +1006,13 @@ static int 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);
-               val &= ~AFI_PEX_CTRL_RST;
-               afi_writel(val, reg);
+       /* Enable slot clock and ensure reset signal 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_readl(reg) | AFI_PEX_CTRL_RST;
+               val &= ~AFI_PEX_CTRL_RST;
                afi_writel(val, reg);
        }
        afi_writel(0, AFI_PEXBIAS_CTRL_0);
@@ -1116,6 +1123,17 @@ static int tegra_pcie_enable_controller(void)
                        }
                } 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);