kirkwood: switch to 3.14
[openwrt.git] / target / linux / kirkwood / patches-3.10 / 0017-pci-mvebu-no-longer-fake-the-slot-location-of-downst.patch
1 From 5db3b7ccb319679ac9c5791112c7eb42c25331e3 Mon Sep 17 00:00:00 2001
2 From: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
3 Date: Thu, 23 May 2013 16:32:51 +0200
4 Subject: [PATCH 17/29] pci: mvebu: no longer fake the slot location of
5  downstream devices
6
7 By default, the Marvell hardware, for each PCIe interface, exhibits
8 the following devices:
9
10  * On slot 0, a "Marvell Memory controller", identical on all PCIe
11    interfaces, and which isn't useful when the Marvell SoC is the PCIe
12    root complex (i.e, the normal case when we run Linux on the Marvell
13    SoC).
14
15  * On slot 1, the real PCIe card connected into the PCIe slot of the
16    board.
17
18 So, what the Marvell PCIe driver was doing in its PCI-to-PCI bridge
19 emulation is that when the Linux PCI core was trying to access the
20 device in slot 0, we were in fact forwarding the configuration
21 transaction to the device in slot 1. For all other slots, we were
22 telling the Linux PCI core that there was no device connected.
23
24 However, new versions of bootloaders from Marvell change the default
25 PCIe configuration, and make the real device appear in slot 0, and the
26 "Marvell Memory controller" in slot 1.
27
28 Therefore, this commit modifies the Marvell PCIe driver to adjust the
29 PCIe hardware configuration to make sure that this behavior (real
30 device in slot 0, "Marvell Memory controller" in slot 1) is the one
31 we'll see regardless of what the bootloader has done. It allows to
32 remove the little hack that was forwarding configuration transactions
33 on slot 0 to slot 1, which is nice.
34
35 Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
36 Acked-by: Bjorn Helgaas <bhelgaas@google.com>
37 Signed-off-by: Jason Cooper <jason@lakedaemon.net>
38 ---
39  drivers/pci/host/pci-mvebu.c | 19 +++++++++++++++----
40  1 file changed, 15 insertions(+), 4 deletions(-)
41
42 --- a/drivers/pci/host/pci-mvebu.c
43 +++ b/drivers/pci/host/pci-mvebu.c
44 @@ -51,6 +51,7 @@
45  #define  PCIE_CTRL_X1_MODE             0x0001
46  #define PCIE_STAT_OFF          0x1a04
47  #define  PCIE_STAT_BUS                  0xff00
48 +#define  PCIE_STAT_DEV                  0x1f0000
49  #define  PCIE_STAT_LINK_DOWN           BIT(0)
50  #define PCIE_DEBUG_CTRL         0x1a60
51  #define  PCIE_DEBUG_SOFT_RESET         BIT(20)
52 @@ -148,6 +149,16 @@ static void mvebu_pcie_set_local_bus_nr(
53         writel(stat, port->base + PCIE_STAT_OFF);
54  }
55  
56 +static void mvebu_pcie_set_local_dev_nr(struct mvebu_pcie_port *port, int nr)
57 +{
58 +       u32 stat;
59 +
60 +       stat = readl(port->base + PCIE_STAT_OFF);
61 +       stat &= ~PCIE_STAT_DEV;
62 +       stat |= nr << 16;
63 +       writel(stat, port->base + PCIE_STAT_OFF);
64 +}
65 +
66  /*
67   * Setup PCIE BARs and Address Decode Wins:
68   * BAR[0,2] -> disabled, BAR[1] -> covers all DRAM banks
69 @@ -572,8 +583,7 @@ static int mvebu_pcie_wr_conf(struct pci
70  
71         /* Access the real PCIe interface */
72         spin_lock_irqsave(&port->conf_lock, flags);
73 -       ret = mvebu_pcie_hw_wr_conf(port, bus,
74 -                                   PCI_DEVFN(1, PCI_FUNC(devfn)),
75 +       ret = mvebu_pcie_hw_wr_conf(port, bus, devfn,
76                                     where, size, val);
77         spin_unlock_irqrestore(&port->conf_lock, flags);
78  
79 @@ -606,8 +616,7 @@ static int mvebu_pcie_rd_conf(struct pci
80  
81         /* Access the real PCIe interface */
82         spin_lock_irqsave(&port->conf_lock, flags);
83 -       ret = mvebu_pcie_hw_rd_conf(port, bus,
84 -                                   PCI_DEVFN(1, PCI_FUNC(devfn)),
85 +       ret = mvebu_pcie_hw_rd_conf(port, bus, devfn,
86                                     where, size, val);
87         spin_unlock_irqrestore(&port->conf_lock, flags);
88  
89 @@ -817,6 +826,8 @@ static int __init mvebu_pcie_probe(struc
90                         continue;
91                 }
92  
93 +               mvebu_pcie_set_local_dev_nr(port, 1);
94 +
95                 if (mvebu_pcie_link_up(port)) {
96                         port->haslink = 1;
97                         dev_info(&pdev->dev, "PCIe%d.%d: link up\n",