Skip to content

Commit

Permalink
[ARM] orion/kirkwood: reset PCIe unit on boot
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Olaf Rempel authored and Nicolas Pitre committed Jul 17, 2010
1 parent 6f2b186 commit 21f0ba9
Showing 1 changed file with 34 additions and 0 deletions.
34 changes: 34 additions & 0 deletions arch/arm/plat-orion/pcie.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <linux/mbus.h>
#include <asm/mach/pci.h>
#include <plat/pcie.h>
#include <linux/delay.h>

/*
* PCIe unit register offsets.
Expand Down Expand Up @@ -46,6 +47,8 @@
#define PCIE_STAT_BUS_OFFS 8
#define PCIE_STAT_BUS_MASK 0xff
#define PCIE_STAT_LINK_DOWN 1
#define PCIE_DEBUG_CTRL 0x1a60
#define PCIE_DEBUG_SOFT_RESET (1<<20)


u32 __init orion_pcie_dev_id(void __iomem *base)
Expand Down Expand Up @@ -85,6 +88,32 @@ void __init orion_pcie_set_local_bus_nr(void __iomem *base, int nr)
writel(stat, base + PCIE_STAT_OFF);
}

void __init orion_pcie_reset(void __iomem *base)
{
u32 reg;
int i;

/*
* MV-S104860-U0, Rev. C:
* PCI Express Unit Soft Reset
* When set, generates an internal reset in the PCI Express unit.
* This bit should be cleared after the link is re-established.
*/
reg = readl(base + PCIE_DEBUG_CTRL);
reg |= PCIE_DEBUG_SOFT_RESET;
writel(reg, base + PCIE_DEBUG_CTRL);

for (i = 0; i < 20; i++) {
mdelay(10);

if (orion_pcie_link_up(base))
break;
}

reg &= ~(PCIE_DEBUG_SOFT_RESET);
writel(reg, base + PCIE_DEBUG_CTRL);
}

/*
* Setup PCIE BARs and Address Decode Wins:
* BAR[0,2] -> disabled, BAR[1] -> covers all DRAM banks
Expand Down Expand Up @@ -152,6 +181,11 @@ void __init orion_pcie_setup(void __iomem *base,
u16 cmd;
u32 mask;

/*
* soft reset PCIe unit
*/
orion_pcie_reset(base);

/*
* Point PCIe unit MBUS decode windows to DRAM space.
*/
Expand Down

0 comments on commit 21f0ba9

Please sign in to comment.