b9020a5ac89f28aea6e617ce8e817e632ffb33ec
[openwrt/openwrt.git] / target / linux / bcm53xx / patches-4.1 / 143-PCI-iproc-Fix-PCIe-reset-logic.patch
1 From 199ff14100095d52cd1b232cc0f3b12f348b5b07 Mon Sep 17 00:00:00 2001
2 From: Ray Jui <rjui@broadcom.com>
3 Date: Tue, 15 Sep 2015 17:39:18 -0700
4 Subject: [PATCH 143/147] PCI: iproc: Fix PCIe reset logic
5
6 The current reset logic does not always properly reset the device. For
7 example, in the case when the perst_b signal is already de-asserted in the
8 bootloader, the current reset logic fails to trigger a proper assert ->
9 de-assert reset sequence.
10
11 Fix the issue by always triggering the proper reset sequence.
12
13 Also explicitly select the desired reset source, i.e., perst_b, and reduce
14 the wait time after the device comes out of reset from 250 ms to 100 ms,
15 based on recommendation from the ASIC team.
16
17 Tested-by: Vladimir Dreizin <vdreizin@broadcom.com>
18 Tested-by: Darren Edamura <dedamura@broadcom.com>
19 Signed-off-by: Ray Jui <rjui@broadcom.com>
20 Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
21 Reviewed-by: Vladimir Dreizin <vdreizin@broadcom.com>
22 Reviewed-by: Trac Hoang <trhoang@broadcom.com>
23 Reviewed-by: Scott Branden <sbranden@broadcom.com>
24 ---
25 drivers/pci/host/pcie-iproc.c | 15 ++++++++++-----
26 1 file changed, 10 insertions(+), 5 deletions(-)
27
28 --- a/drivers/pci/host/pcie-iproc.c
29 +++ b/drivers/pci/host/pcie-iproc.c
30 @@ -31,6 +31,8 @@
31 #include "pcie-iproc.h"
32
33 #define CLK_CONTROL_OFFSET 0x000
34 +#define EP_PERST_SOURCE_SELECT_SHIFT 2
35 +#define EP_PERST_SOURCE_SELECT BIT(EP_PERST_SOURCE_SELECT_SHIFT)
36 #define EP_MODE_SURVIVE_PERST_SHIFT 1
37 #define EP_MODE_SURVIVE_PERST BIT(EP_MODE_SURVIVE_PERST_SHIFT)
38 #define RC_PCIE_RST_OUTPUT_SHIFT 0
39 @@ -119,15 +121,18 @@ static void iproc_pcie_reset(struct ipro
40 u32 val;
41
42 /*
43 - * Configure the PCIe controller as root complex and send a downstream
44 - * reset
45 + * Select perst_b signal as reset source. Put the device into reset,
46 + * and then bring it out of reset
47 */
48 - val = EP_MODE_SURVIVE_PERST | RC_PCIE_RST_OUTPUT;
49 + val = readl(pcie->base + CLK_CONTROL_OFFSET);
50 + val &= ~EP_PERST_SOURCE_SELECT & ~EP_MODE_SURVIVE_PERST &
51 + ~RC_PCIE_RST_OUTPUT;
52 writel(val, pcie->base + CLK_CONTROL_OFFSET);
53 udelay(250);
54 - val &= ~EP_MODE_SURVIVE_PERST;
55 +
56 + val |= RC_PCIE_RST_OUTPUT;
57 writel(val, pcie->base + CLK_CONTROL_OFFSET);
58 - msleep(250);
59 + msleep(100);
60 }
61
62 static int iproc_pcie_check_link(struct iproc_pcie *pcie, struct pci_bus *bus)