aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorOlaf Rempel <razzor@kopf-tisch.de>2010-06-08 16:32:38 -0400
committerNicolas Pitre <nico@fluxnic.net>2010-07-16 22:01:57 -0400
commit21f0ba90a447090153edeaf2f14f9f7e8bd9bc80 (patch)
tree89daf1b0ba284bf0ed43e5f75ff910ff120ca781 /arch/arm
parent6f2b186a0f1e70be411ca260d4577f1ed35d58e0 (diff)
[ARM] orion/kirkwood: reset PCIe unit on boot
Patch found in QNAPs vendor source package, with some cleanups (proper defines, shortened max. timeout from 1s to 200ms). Without this patch the PCIe SATA controller (Marvell 88sx7042/sata_mv) in my QNAP TS-419P (Marvell 88f6281/Kirkwood) stops working after a few minutes. The symptomes are described in this thread: http://marc.info/?l=linux-ide&m=124822863706181&w=2 [ Note: this is a workaround in need of a better analysis/solution -- NP ] Acked-by: Saeed Bishara <saeed@marvell.com> Tested-by: Bernhard R. Link <brl@pcpool00.mathematik.uni-freiburg.de> Seconded-by: Martin Michlmayr <tbm@cyrius.com> I'm_not_very_happy_with_it-by: Lennert Buytenhek <buytenh@wantstofly.org> Signed-off-by: Nicolas Pitre <nico@fluxnic.net>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/plat-orion/pcie.c34
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
51u32 __init orion_pcie_dev_id(void __iomem *base) 54u32 __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
91void __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);