diff options
Diffstat (limited to 'arch/arm/plat-orion/pcie.c')
-rw-r--r-- | arch/arm/plat-orion/pcie.c | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/arch/arm/plat-orion/pcie.c b/arch/arm/plat-orion/pcie.c index 54c84a492a0f..779553a1595e 100644 --- a/arch/arm/plat-orion/pcie.c +++ b/arch/arm/plat-orion/pcie.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/mbus.h> | 13 | #include <linux/mbus.h> |
14 | #include <asm/mach/pci.h> | 14 | #include <asm/mach/pci.h> |
15 | #include <plat/pcie.h> | 15 | #include <plat/pcie.h> |
16 | #include <linux/delay.h> | ||
16 | 17 | ||
17 | /* | 18 | /* |
18 | * PCIe unit register offsets. | 19 | * PCIe unit register offsets. |
@@ -46,6 +47,8 @@ | |||
46 | #define PCIE_STAT_BUS_OFFS 8 | 47 | #define PCIE_STAT_BUS_OFFS 8 |
47 | #define PCIE_STAT_BUS_MASK 0xff | 48 | #define PCIE_STAT_BUS_MASK 0xff |
48 | #define PCIE_STAT_LINK_DOWN 1 | 49 | #define PCIE_STAT_LINK_DOWN 1 |
50 | #define PCIE_DEBUG_CTRL 0x1a60 | ||
51 | #define PCIE_DEBUG_SOFT_RESET (1<<20) | ||
49 | 52 | ||
50 | 53 | ||
51 | u32 __init orion_pcie_dev_id(void __iomem *base) | 54 | u32 __init orion_pcie_dev_id(void __iomem *base) |
@@ -85,6 +88,32 @@ void __init orion_pcie_set_local_bus_nr(void __iomem *base, int nr) | |||
85 | writel(stat, base + PCIE_STAT_OFF); | 88 | writel(stat, base + PCIE_STAT_OFF); |
86 | } | 89 | } |
87 | 90 | ||
91 | void __init orion_pcie_reset(void __iomem *base) | ||
92 | { | ||
93 | u32 reg; | ||
94 | int i; | ||
95 | |||
96 | /* | ||
97 | * MV-S104860-U0, Rev. C: | ||
98 | * PCI Express Unit Soft Reset | ||
99 | * When set, generates an internal reset in the PCI Express unit. | ||
100 | * This bit should be cleared after the link is re-established. | ||
101 | */ | ||
102 | reg = readl(base + PCIE_DEBUG_CTRL); | ||
103 | reg |= PCIE_DEBUG_SOFT_RESET; | ||
104 | writel(reg, base + PCIE_DEBUG_CTRL); | ||
105 | |||
106 | for (i = 0; i < 20; i++) { | ||
107 | mdelay(10); | ||
108 | |||
109 | if (orion_pcie_link_up(base)) | ||
110 | break; | ||
111 | } | ||
112 | |||
113 | reg &= ~(PCIE_DEBUG_SOFT_RESET); | ||
114 | writel(reg, base + PCIE_DEBUG_CTRL); | ||
115 | } | ||
116 | |||
88 | /* | 117 | /* |
89 | * Setup PCIE BARs and Address Decode Wins: | 118 | * Setup PCIE BARs and Address Decode Wins: |
90 | * BAR[0,2] -> disabled, BAR[1] -> covers all DRAM banks | 119 | * BAR[0,2] -> disabled, BAR[1] -> covers all DRAM banks |
@@ -153,6 +182,11 @@ void __init orion_pcie_setup(void __iomem *base, | |||
153 | u32 mask; | 182 | u32 mask; |
154 | 183 | ||
155 | /* | 184 | /* |
185 | * soft reset PCIe unit | ||
186 | */ | ||
187 | orion_pcie_reset(base); | ||
188 | |||
189 | /* | ||
156 | * Point PCIe unit MBUS decode windows to DRAM space. | 190 | * Point PCIe unit MBUS decode windows to DRAM space. |
157 | */ | 191 | */ |
158 | orion_pcie_setup_wins(base, dram); | 192 | orion_pcie_setup_wins(base, dram); |