Commit 843a85ce authored by Bjorn Helgaas's avatar Bjorn Helgaas

Merge branches 'pci/host-designware', 'pci/host-imx6', 'pci/host-mvebu' and...

Merge branches 'pci/host-designware', 'pci/host-imx6', 'pci/host-mvebu' and 'pci/host-tegra' into next

* pci/host-designware:
  PCI: designware: Remove unnecessary use of 'conf_lock' spinlock
  PCI: designware: Use new OF interrupt mapping when possible
  PCI: designware: Fix iATU programming for cfg1, io and mem viewport
  PCI: designware: Fix comment for setting number of lanes

* pci/host-imx6:
  PCI: designware: Split Exynos and i.MX bindings

* pci/host-mvebu:
  PCI: mvebu: Use '%pa' for printing 'phys_addr_t' type
  PCI: mvebu: Remove unnecessary use of 'conf_lock' spinlock
  PCI: mvebu: split PCIe BARs into multiple MBus windows when needed
  bus: mvebu-mbus: allow several windows with the same target/attribute
  bus: mvebu-mbus: Avoid setting an undefined window size
  PCI: mvebu: fix off-by-one in the computed size of the mbus windows

* pci/host-tegra:
  PCI: tegra: Use new OF interrupt mapping when possible
* Synopsys Designware PCIe interface * Synopsys Designware PCIe interface
Required properties: Required properties:
- compatible: should contain "snps,dw-pcie" to identify the - compatible: should contain "snps,dw-pcie" to identify the core.
core, plus an identifier for the specific instance, such
as "samsung,exynos5440-pcie" or "fsl,imx6q-pcie".
- reg: base addresses and lengths of the pcie controller,
the phy controller, additional register for the phy controller.
- interrupts: interrupt values for level interrupt,
pulse interrupt, special interrupt.
- clocks: from common clock binding: handle to pci clock.
- clock-names: from common clock binding: should be "pcie" and "pcie_bus".
- #address-cells: set to <3> - #address-cells: set to <3>
- #size-cells: set to <2> - #size-cells: set to <2>
- device_type: set to "pci" - device_type: set to "pci"
...@@ -19,65 +11,11 @@ Required properties: ...@@ -19,65 +11,11 @@ Required properties:
to define the mapping of the PCIe interface to interrupt to define the mapping of the PCIe interface to interrupt
numbers. numbers.
- num-lanes: number of lanes to use - num-lanes: number of lanes to use
- clocks: Must contain an entry for each entry in clock-names.
See ../clocks/clock-bindings.txt for details.
- clock-names: Must include the following entries:
- "pcie"
- "pcie_bus"
Optional properties: Optional properties:
- reset-gpio: gpio pin number of power good signal - reset-gpio: gpio pin number of power good signal
Optional properties for fsl,imx6q-pcie
- power-on-gpio: gpio pin number of power-enable signal
- wake-up-gpio: gpio pin number of incoming wakeup signal
- disable-gpio: gpio pin number of outgoing rfkill/endpoint disable signal
Example:
SoC specific DT Entry:
pcie@290000 {
compatible = "samsung,exynos5440-pcie", "snps,dw-pcie";
reg = <0x290000 0x1000
0x270000 0x1000
0x271000 0x40>;
interrupts = <0 20 0>, <0 21 0>, <0 22 0>;
clocks = <&clock 28>, <&clock 27>;
clock-names = "pcie", "pcie_bus";
#address-cells = <3>;
#size-cells = <2>;
device_type = "pci";
ranges = <0x00000800 0 0x40000000 0x40000000 0 0x00001000 /* configuration space */
0x81000000 0 0 0x40001000 0 0x00010000 /* downstream I/O */
0x82000000 0 0x40011000 0x40011000 0 0x1ffef000>; /* non-prefetchable memory */
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 0>;
interrupt-map = <0x0 0 &gic 53>;
num-lanes = <4>;
};
pcie@2a0000 {
compatible = "samsung,exynos5440-pcie", "snps,dw-pcie";
reg = <0x2a0000 0x1000
0x272000 0x1000
0x271040 0x40>;
interrupts = <0 23 0>, <0 24 0>, <0 25 0>;
clocks = <&clock 29>, <&clock 27>;
clock-names = "pcie", "pcie_bus";
#address-cells = <3>;
#size-cells = <2>;
device_type = "pci";
ranges = <0x00000800 0 0x60000000 0x60000000 0 0x00001000 /* configuration space */
0x81000000 0 0 0x60001000 0 0x00010000 /* downstream I/O */
0x82000000 0 0x60011000 0x60011000 0 0x1ffef000>; /* non-prefetchable memory */
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 0>;
interrupt-map = <0x0 0 &gic 56>;
num-lanes = <4>;
};
Board specific DT Entry:
pcie@290000 {
reset-gpio = <&pin_ctrl 5 0>;
};
pcie@2a0000 {
reset-gpio = <&pin_ctrl 22 0>;
};
* Freescale i.MX6 PCIe interface
This PCIe host controller is based on the Synopsis Designware PCIe IP
and thus inherits all the common properties defined in designware-pcie.txt.
Required properties:
- compatible: "fsl,imx6q-pcie"
- reg: base addresse and length of the pcie controller
- interrupts: A list of interrupt outputs of the controller. Must contain an
entry for each entry in the interrupt-names property.
- interrupt-names: Must include the following entries:
- "msi": The interrupt that is asserted when an MSI is received
- clock-names: Must include the following additional entries:
- "pcie_phy"
Example:
pcie@0x01000000 {
compatible = "fsl,imx6q-pcie", "snps,dw-pcie";
reg = <0x01ffc000 0x4000>;
#address-cells = <3>;
#size-cells = <2>;
device_type = "pci";
ranges = <0x00000800 0 0x01f00000 0x01f00000 0 0x00080000
0x81000000 0 0 0x01f80000 0 0x00010000
0x82000000 0 0x01000000 0x01000000 0 0x00f00000>;
num-lanes = <1>;
interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "msi";
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 0x7>;
interrupt-map = <0 0 0 1 &intc GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>,
<0 0 0 2 &intc GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
<0 0 0 3 &intc GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
<0 0 0 4 &intc GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks 144>, <&clks 206>, <&clks 189>;
clock-names = "pcie", "pcie_bus", "pcie_phy";
};
* Samsung Exynos 5440 PCIe interface
This PCIe host controller is based on the Synopsis Designware PCIe IP
and thus inherits all the common properties defined in designware-pcie.txt.
Required properties:
- compatible: "samsung,exynos5440-pcie"
- reg: base addresses and lengths of the pcie controller,
the phy controller, additional register for the phy controller.
- interrupts: A list of interrupt outputs for level interrupt,
pulse interrupt, special interrupt.
Example:
SoC specific DT Entry:
pcie@290000 {
compatible = "samsung,exynos5440-pcie", "snps,dw-pcie";
reg = <0x290000 0x1000
0x270000 0x1000
0x271000 0x40>;
interrupts = <0 20 0>, <0 21 0>, <0 22 0>;
clocks = <&clock 28>, <&clock 27>;
clock-names = "pcie", "pcie_bus";
#address-cells = <3>;
#size-cells = <2>;
device_type = "pci";
ranges = <0x00000800 0 0x40000000 0x40000000 0 0x00001000 /* configuration space */
0x81000000 0 0 0x40001000 0 0x00010000 /* downstream I/O */
0x82000000 0 0x40011000 0x40011000 0 0x1ffef000>; /* non-prefetchable memory */
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 0>;
interrupt-map = <0 0 0 0 &gic GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
num-lanes = <4>;
};
pcie@2a0000 {
compatible = "samsung,exynos5440-pcie", "snps,dw-pcie";
reg = <0x2a0000 0x1000
0x272000 0x1000
0x271040 0x40>;
interrupts = <0 23 0>, <0 24 0>, <0 25 0>;
clocks = <&clock 29>, <&clock 27>;
clock-names = "pcie", "pcie_bus";
#address-cells = <3>;
#size-cells = <2>;
device_type = "pci";
ranges = <0x00000800 0 0x60000000 0x60000000 0 0x00001000 /* configuration space */
0x81000000 0 0 0x60001000 0 0x00010000 /* downstream I/O */
0x82000000 0 0x60011000 0x60011000 0 0x1ffef000>; /* non-prefetchable memory */
#interrupt-cells = <1>;
interrupt-map-mask = <0 0 0 0>;
interrupt-map = <0 0 0 0 &gic GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
num-lanes = <4>;
};
Board specific DT Entry:
pcie@290000 {
reset-gpio = <&pin_ctrl 5 0>;
};
pcie@2a0000 {
reset-gpio = <&pin_ctrl 22 0>;
};
...@@ -56,6 +56,7 @@ ...@@ -56,6 +56,7 @@
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_address.h> #include <linux/of_address.h>
#include <linux/debugfs.h> #include <linux/debugfs.h>
#include <linux/log2.h>
/* /*
* DDR target is the same on all platforms. * DDR target is the same on all platforms.
...@@ -222,12 +223,6 @@ static int mvebu_mbus_window_conflicts(struct mvebu_mbus_state *mbus, ...@@ -222,12 +223,6 @@ static int mvebu_mbus_window_conflicts(struct mvebu_mbus_state *mbus,
*/ */
if ((u64)base < wend && end > wbase) if ((u64)base < wend && end > wbase)
return 0; return 0;
/*
* Check if target/attribute conflicts
*/
if (target == wtarget && attr == wattr)
return 0;
} }
return 1; return 1;
...@@ -266,6 +261,17 @@ static int mvebu_mbus_setup_window(struct mvebu_mbus_state *mbus, ...@@ -266,6 +261,17 @@ static int mvebu_mbus_setup_window(struct mvebu_mbus_state *mbus,
mbus->soc->win_cfg_offset(win); mbus->soc->win_cfg_offset(win);
u32 ctrl, remap_addr; u32 ctrl, remap_addr;
if (!is_power_of_2(size)) {
WARN(true, "Invalid MBus window size: 0x%zx\n", size);
return -EINVAL;
}
if ((base & (phys_addr_t)(size - 1)) != 0) {
WARN(true, "Invalid MBus base/size: %pa len 0x%zx\n", &base,
size);
return -EINVAL;
}
ctrl = ((size - 1) & WIN_CTRL_SIZE_MASK) | ctrl = ((size - 1) & WIN_CTRL_SIZE_MASK) |
(attr << WIN_CTRL_ATTR_SHIFT) | (attr << WIN_CTRL_ATTR_SHIFT) |
(target << WIN_CTRL_TGT_SHIFT) | (target << WIN_CTRL_TGT_SHIFT) |
...@@ -413,6 +419,10 @@ static int mvebu_devs_debug_show(struct seq_file *seq, void *v) ...@@ -413,6 +419,10 @@ static int mvebu_devs_debug_show(struct seq_file *seq, void *v)
win, (unsigned long long)wbase, win, (unsigned long long)wbase,
(unsigned long long)(wbase + wsize), wtarget, wattr); (unsigned long long)(wbase + wsize), wtarget, wattr);
if (!is_power_of_2(wsize) ||
((wbase & (u64)(wsize - 1)) != 0))
seq_puts(seq, " (Invalid base/size!!)");
if (win < mbus->soc->num_remappable_wins) { if (win < mbus->soc->num_remappable_wins) {
seq_printf(seq, " (remap %016llx)\n", seq_printf(seq, " (remap %016llx)\n",
(unsigned long long)wremap); (unsigned long long)wremap);
......
...@@ -545,7 +545,6 @@ static int __init add_pcie_port(struct pcie_port *pp, ...@@ -545,7 +545,6 @@ static int __init add_pcie_port(struct pcie_port *pp,
pp->root_bus_nr = -1; pp->root_bus_nr = -1;
pp->ops = &exynos_pcie_host_ops; pp->ops = &exynos_pcie_host_ops;
spin_lock_init(&pp->conf_lock);
ret = dw_pcie_host_init(pp); ret = dw_pcie_host_init(pp);
if (ret) { if (ret) {
dev_err(&pdev->dev, "failed to initialize host\n"); dev_err(&pdev->dev, "failed to initialize host\n");
......
...@@ -507,7 +507,6 @@ static int __init imx6_add_pcie_port(struct pcie_port *pp, ...@@ -507,7 +507,6 @@ static int __init imx6_add_pcie_port(struct pcie_port *pp,
pp->root_bus_nr = -1; pp->root_bus_nr = -1;
pp->ops = &imx6_pcie_host_ops; pp->ops = &imx6_pcie_host_ops;
spin_lock_init(&pp->conf_lock);
ret = dw_pcie_host_init(pp); ret = dw_pcie_host_init(pp);
if (ret) { if (ret) {
dev_err(&pdev->dev, "failed to initialize host\n"); dev_err(&pdev->dev, "failed to initialize host\n");
......
...@@ -113,7 +113,6 @@ struct mvebu_pcie { ...@@ -113,7 +113,6 @@ struct mvebu_pcie {
struct mvebu_pcie_port { struct mvebu_pcie_port {
char *name; char *name;
void __iomem *base; void __iomem *base;
spinlock_t conf_lock;
u32 port; u32 port;
u32 lane; u32 lane;
int devfn; int devfn;
...@@ -293,6 +292,60 @@ static int mvebu_pcie_hw_wr_conf(struct mvebu_pcie_port *port, ...@@ -293,6 +292,60 @@ static int mvebu_pcie_hw_wr_conf(struct mvebu_pcie_port *port,
return PCIBIOS_SUCCESSFUL; return PCIBIOS_SUCCESSFUL;
} }
/*
* Remove windows, starting from the largest ones to the smallest
* ones.
*/
static void mvebu_pcie_del_windows(struct mvebu_pcie_port *port,
phys_addr_t base, size_t size)
{
while (size) {
size_t sz = 1 << (fls(size) - 1);
mvebu_mbus_del_window(base, sz);
base += sz;
size -= sz;
}
}
/*
* MBus windows can only have a power of two size, but PCI BARs do not
* have this constraint. Therefore, we have to split the PCI BAR into
* areas each having a power of two size. We start from the largest
* one (i.e highest order bit set in the size).
*/
static void mvebu_pcie_add_windows(struct mvebu_pcie_port *port,
unsigned int target, unsigned int attribute,
phys_addr_t base, size_t size,
phys_addr_t remap)
{
size_t size_mapped = 0;
while (size) {
size_t sz = 1 << (fls(size) - 1);
int ret;
ret = mvebu_mbus_add_window_remap_by_id(target, attribute, base,
sz, remap);
if (ret) {
phys_addr_t end = base + sz - 1;
dev_err(&port->pcie->pdev->dev,
"Could not create MBus window at [mem %pa-%pa]: %d\n",
&base, &end, ret);
mvebu_pcie_del_windows(port, base - size_mapped,
size_mapped);
return;
}
size -= sz;
size_mapped += sz;
base += sz;
if (remap != MVEBU_MBUS_NO_REMAP)
remap += sz;
}
}
static void mvebu_pcie_handle_iobase_change(struct mvebu_pcie_port *port) static void mvebu_pcie_handle_iobase_change(struct mvebu_pcie_port *port)
{ {
phys_addr_t iobase; phys_addr_t iobase;
...@@ -304,8 +357,8 @@ static void mvebu_pcie_handle_iobase_change(struct mvebu_pcie_port *port) ...@@ -304,8 +357,8 @@ static void mvebu_pcie_handle_iobase_change(struct mvebu_pcie_port *port)
/* If a window was configured, remove it */ /* If a window was configured, remove it */
if (port->iowin_base) { if (port->iowin_base) {
mvebu_mbus_del_window(port->iowin_base, mvebu_pcie_del_windows(port, port->iowin_base,
port->iowin_size); port->iowin_size);
port->iowin_base = 0; port->iowin_base = 0;
port->iowin_size = 0; port->iowin_size = 0;
} }
...@@ -331,11 +384,11 @@ static void mvebu_pcie_handle_iobase_change(struct mvebu_pcie_port *port) ...@@ -331,11 +384,11 @@ static void mvebu_pcie_handle_iobase_change(struct mvebu_pcie_port *port)
port->iowin_base = port->pcie->io.start + iobase; port->iowin_base = port->pcie->io.start + iobase;
port->iowin_size = ((0xFFF | ((port->bridge.iolimit & 0xF0) << 8) | port->iowin_size = ((0xFFF | ((port->bridge.iolimit & 0xF0) << 8) |
(port->bridge.iolimitupper << 16)) - (port->bridge.iolimitupper << 16)) -
iobase); iobase) + 1;
mvebu_mbus_add_window_remap_by_id(port->io_target, port->io_attr, mvebu_pcie_add_windows(port, port->io_target, port->io_attr,
port->iowin_base, port->iowin_size, port->iowin_base, port->iowin_size,
iobase); iobase);
} }
static void mvebu_pcie_handle_membase_change(struct mvebu_pcie_port *port) static void mvebu_pcie_handle_membase_change(struct mvebu_pcie_port *port)
...@@ -346,8 +399,8 @@ static void mvebu_pcie_handle_membase_change(struct mvebu_pcie_port *port) ...@@ -346,8 +399,8 @@ static void mvebu_pcie_handle_membase_change(struct mvebu_pcie_port *port)
/* If a window was configured, remove it */ /* If a window was configured, remove it */
if (port->memwin_base) { if (port->memwin_base) {
mvebu_mbus_del_window(port->memwin_base, mvebu_pcie_del_windows(port, port->memwin_base,
port->memwin_size); port->memwin_size);
port->memwin_base = 0; port->memwin_base = 0;
port->memwin_size = 0; port->memwin_size = 0;
} }
...@@ -364,10 +417,11 @@ static void mvebu_pcie_handle_membase_change(struct mvebu_pcie_port *port) ...@@ -364,10 +417,11 @@ static void mvebu_pcie_handle_membase_change(struct mvebu_pcie_port *port)
port->memwin_base = ((port->bridge.membase & 0xFFF0) << 16); port->memwin_base = ((port->bridge.membase & 0xFFF0) << 16);
port->memwin_size = port->memwin_size =
(((port->bridge.memlimit & 0xFFF0) << 16) | 0xFFFFF) - (((port->bridge.memlimit & 0xFFF0) << 16) | 0xFFFFF) -
port->memwin_base; port->memwin_base + 1;
mvebu_mbus_add_window_by_id(port->mem_target, port->mem_attr, mvebu_pcie_add_windows(port, port->mem_target, port->mem_attr,
port->memwin_base, port->memwin_size); port->memwin_base, port->memwin_size,
MVEBU_MBUS_NO_REMAP);
} }
/* /*
...@@ -585,7 +639,6 @@ static int mvebu_pcie_wr_conf(struct pci_bus *bus, u32 devfn, ...@@ -585,7 +639,6 @@ static int mvebu_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
{ {
struct mvebu_pcie *pcie = sys_to_pcie(bus->sysdata); struct mvebu_pcie *pcie = sys_to_pcie(bus->sysdata);
struct mvebu_pcie_port *port; struct mvebu_pcie_port *port;
unsigned long flags;
int ret; int ret;
port = mvebu_pcie_find_port(pcie, bus, devfn); port = mvebu_pcie_find_port(pcie, bus, devfn);
...@@ -611,10 +664,8 @@ static int mvebu_pcie_wr_conf(struct pci_bus *bus, u32 devfn, ...@@ -611,10 +664,8 @@ static int mvebu_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
return PCIBIOS_DEVICE_NOT_FOUND; return PCIBIOS_DEVICE_NOT_FOUND;
/* Access the real PCIe interface */ /* Access the real PCIe interface */
spin_lock_irqsave(&port->conf_lock, flags);
ret = mvebu_pcie_hw_wr_conf(port, bus, devfn, ret = mvebu_pcie_hw_wr_conf(port, bus, devfn,
where, size, val); where, size, val);
spin_unlock_irqrestore(&port->conf_lock, flags);
return ret; return ret;
} }
...@@ -625,7 +676,6 @@ static int mvebu_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, ...@@ -625,7 +676,6 @@ static int mvebu_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
{ {
struct mvebu_pcie *pcie = sys_to_pcie(bus->sysdata); struct mvebu_pcie *pcie = sys_to_pcie(bus->sysdata);
struct mvebu_pcie_port *port; struct mvebu_pcie_port *port;
unsigned long flags;
int ret; int ret;
port = mvebu_pcie_find_port(pcie, bus, devfn); port = mvebu_pcie_find_port(pcie, bus, devfn);
...@@ -657,10 +707,8 @@ static int mvebu_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, ...@@ -657,10 +707,8 @@ static int mvebu_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
} }
/* Access the real PCIe interface */ /* Access the real PCIe interface */
spin_lock_irqsave(&port->conf_lock, flags);
ret = mvebu_pcie_hw_rd_conf(port, bus, devfn, ret = mvebu_pcie_hw_rd_conf(port, bus, devfn,
where, size, val); where, size, val);
spin_unlock_irqrestore(&port->conf_lock, flags);
return ret; return ret;
} }
...@@ -743,14 +791,21 @@ static resource_size_t mvebu_pcie_align_resource(struct pci_dev *dev, ...@@ -743,14 +791,21 @@ static resource_size_t mvebu_pcie_align_resource(struct pci_dev *dev,
/* /*
* On the PCI-to-PCI bridge side, the I/O windows must have at * On the PCI-to-PCI bridge side, the I/O windows must have at
* least a 64 KB size and be aligned on their size, and the * least a 64 KB size and the memory windows must have at
* memory windows must have at least a 1 MB size and be * least a 1 MB size. Moreover, MBus windows need to have a
* aligned on their size * base address aligned on their size, and their size must be
* a power of two. This means that if the BAR doesn't have a
* power of two size, several MBus windows will actually be
* created. We need to ensure that the biggest MBus window
* (which will be the first one) is aligned on its size, which
* explains the rounddown_pow_of_two() being done here.
*/ */
if (res->flags & IORESOURCE_IO) if (res->flags & IORESOURCE_IO)
return round_up(start, max_t(resource_size_t, SZ_64K, size)); return round_up(start, max_t(resource_size_t, SZ_64K,
rounddown_pow_of_two(size)));
else if (res->flags & IORESOURCE_MEM) else if (res->flags & IORESOURCE_MEM)
return round_up(start, max_t(resource_size_t, SZ_1M, size)); return round_up(start, max_t(resource_size_t, SZ_1M,
rounddown_pow_of_two(size)));
else else
return start; return start;
} }
...@@ -1000,7 +1055,6 @@ static int mvebu_pcie_probe(struct platform_device *pdev) ...@@ -1000,7 +1055,6 @@ static int mvebu_pcie_probe(struct platform_device *pdev)
mvebu_pcie_set_local_dev_nr(port, 1); mvebu_pcie_set_local_dev_nr(port, 1);
port->dn = child; port->dn = child;
spin_lock_init(&port->conf_lock);
mvebu_sw_pci_bridge_init(port); mvebu_sw_pci_bridge_init(port);
i++; i++;
} }
......
...@@ -639,10 +639,15 @@ static int tegra_pcie_setup(int nr, struct pci_sys_data *sys) ...@@ -639,10 +639,15 @@ static int tegra_pcie_setup(int nr, struct pci_sys_data *sys)
static int tegra_pcie_map_irq(const struct pci_dev *pdev, u8 slot, u8 pin) static int tegra_pcie_map_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
{ {
struct tegra_pcie *pcie = sys_to_pcie(pdev->bus->sysdata); struct tegra_pcie *pcie = sys_to_pcie(pdev->bus->sysdata);
int irq;
tegra_cpuidle_pcie_irqs_in_use(); tegra_cpuidle_pcie_irqs_in_use();
return pcie->irq; irq = of_irq_parse_and_map_pci(pdev, slot, pin);
if (!irq)
irq = pcie->irq;
return irq;
} }
static void tegra_pcie_add_bus(struct pci_bus *bus) static void tegra_pcie_add_bus(struct pci_bus *bus)
......
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/msi.h> #include <linux/msi.h>
#include <linux/of_address.h> #include <linux/of_address.h>
#include <linux/of_pci.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/pci_regs.h> #include <linux/pci_regs.h>
#include <linux/types.h> #include <linux/types.h>
...@@ -494,7 +495,7 @@ int __init dw_pcie_host_init(struct pcie_port *pp) ...@@ -494,7 +495,7 @@ int __init dw_pcie_host_init(struct pcie_port *pp)
dw_pci.nr_controllers = 1; dw_pci.nr_controllers = 1;
dw_pci.private_data = (void **)&pp; dw_pci.private_data = (void **)&pp;
pci_common_init(&dw_pci); pci_common_init_dev(pp->dev, &dw_pci);
pci_assign_unassigned_resources(); pci_assign_unassigned_resources();
#ifdef CONFIG_PCI_DOMAINS #ifdef CONFIG_PCI_DOMAINS
dw_pci.domain++; dw_pci.domain++;
...@@ -524,13 +525,13 @@ static void dw_pcie_prog_viewport_cfg1(struct pcie_port *pp, u32 busdev) ...@@ -524,13 +525,13 @@ static void dw_pcie_prog_viewport_cfg1(struct pcie_port *pp, u32 busdev)
dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX1, dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX1,
PCIE_ATU_VIEWPORT); PCIE_ATU_VIEWPORT);
dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_CFG1, PCIE_ATU_CR1); dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_CFG1, PCIE_ATU_CR1);
dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
dw_pcie_writel_rc(pp, pp->cfg1_base, PCIE_ATU_LOWER_BASE); dw_pcie_writel_rc(pp, pp->cfg1_base, PCIE_ATU_LOWER_BASE);
dw_pcie_writel_rc(pp, (pp->cfg1_base >> 32), PCIE_ATU_UPPER_BASE); dw_pcie_writel_rc(pp, (pp->cfg1_base >> 32), PCIE_ATU_UPPER_BASE);
dw_pcie_writel_rc(pp, pp->cfg1_base + pp->config.cfg1_size - 1, dw_pcie_writel_rc(pp, pp->cfg1_base + pp->config.cfg1_size - 1,
PCIE_ATU_LIMIT); PCIE_ATU_LIMIT);
dw_pcie_writel_rc(pp, busdev, PCIE_ATU_LOWER_TARGET); dw_pcie_writel_rc(pp, busdev, PCIE_ATU_LOWER_TARGET);
dw_pcie_writel_rc(pp, 0, PCIE_ATU_UPPER_TARGET); dw_pcie_writel_rc(pp, 0, PCIE_ATU_UPPER_TARGET);
dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
} }
static void dw_pcie_prog_viewport_mem_outbound(struct pcie_port *pp) static void dw_pcie_prog_viewport_mem_outbound(struct pcie_port *pp)
...@@ -539,7 +540,6 @@ static void dw_pcie_prog_viewport_mem_outbound(struct pcie_port *pp) ...@@ -539,7 +540,6 @@ static void dw_pcie_prog_viewport_mem_outbound(struct pcie_port *pp)
dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX0, dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX0,
PCIE_ATU_VIEWPORT); PCIE_ATU_VIEWPORT);
dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_MEM, PCIE_ATU_CR1); dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_MEM, PCIE_ATU_CR1);
dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
dw_pcie_writel_rc(pp, pp->mem_base, PCIE_ATU_LOWER_BASE); dw_pcie_writel_rc(pp, pp->mem_base, PCIE_ATU_LOWER_BASE);
dw_pcie_writel_rc(pp, (pp->mem_base >> 32), PCIE_ATU_UPPER_BASE); dw_pcie_writel_rc(pp, (pp->mem_base >> 32), PCIE_ATU_UPPER_BASE);
dw_pcie_writel_rc(pp, pp->mem_base + pp->config.mem_size - 1, dw_pcie_writel_rc(pp, pp->mem_base + pp->config.mem_size - 1,
...@@ -547,6 +547,7 @@ static void dw_pcie_prog_viewport_mem_outbound(struct pcie_port *pp) ...@@ -547,6 +547,7 @@ static void dw_pcie_prog_viewport_mem_outbound(struct pcie_port *pp)
dw_pcie_writel_rc(pp, pp->config.mem_bus_addr, PCIE_ATU_LOWER_TARGET); dw_pcie_writel_rc(pp, pp->config.mem_bus_addr, PCIE_ATU_LOWER_TARGET);
dw_pcie_writel_rc(pp, upper_32_bits(pp->config.mem_bus_addr), dw_pcie_writel_rc(pp, upper_32_bits(pp->config.mem_bus_addr),
PCIE_ATU_UPPER_TARGET); PCIE_ATU_UPPER_TARGET);
dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
} }
static void dw_pcie_prog_viewport_io_outbound(struct pcie_port *pp) static void dw_pcie_prog_viewport_io_outbound(struct pcie_port *pp)
...@@ -555,7 +556,6 @@ static void dw_pcie_prog_viewport_io_outbound(struct pcie_port *pp) ...@@ -555,7 +556,6 @@ static void dw_pcie_prog_viewport_io_outbound(struct pcie_port *pp)
dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX1, dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX1,
PCIE_ATU_VIEWPORT); PCIE_ATU_VIEWPORT);
dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_IO, PCIE_ATU_CR1); dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_IO, PCIE_ATU_CR1);
dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
dw_pcie_writel_rc(pp, pp->io_base, PCIE_ATU_LOWER_BASE); dw_pcie_writel_rc(pp, pp->io_base, PCIE_ATU_LOWER_BASE);
dw_pcie_writel_rc(pp, (pp->io_base >> 32), PCIE_ATU_UPPER_BASE); dw_pcie_writel_rc(pp, (pp->io_base >> 32), PCIE_ATU_UPPER_BASE);
dw_pcie_writel_rc(pp, pp->io_base + pp->config.io_size - 1, dw_pcie_writel_rc(pp, pp->io_base + pp->config.io_size - 1,
...@@ -563,6 +563,7 @@ static void dw_pcie_prog_viewport_io_outbound(struct pcie_port *pp) ...@@ -563,6 +563,7 @@ static void dw_pcie_prog_viewport_io_outbound(struct pcie_port *pp)
dw_pcie_writel_rc(pp, pp->config.io_bus_addr, PCIE_ATU_LOWER_TARGET); dw_pcie_writel_rc(pp, pp->config.io_bus_addr, PCIE_ATU_LOWER_TARGET);
dw_pcie_writel_rc(pp, upper_32_bits(pp->config.io_bus_addr), dw_pcie_writel_rc(pp, upper_32_bits(pp->config.io_bus_addr),
PCIE_ATU_UPPER_TARGET); PCIE_ATU_UPPER_TARGET);
dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
} }
static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus, static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
...@@ -642,7 +643,6 @@ static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, ...@@ -642,7 +643,6 @@ static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
int size, u32 *val) int size, u32 *val)
{ {
struct pcie_port *pp = sys_to_pcie(bus->sysdata); struct pcie_port *pp = sys_to_pcie(bus->sysdata);
unsigned long flags;
int ret; int ret;
if (!pp) { if (!pp) {
...@@ -655,13 +655,11 @@ static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where, ...@@ -655,13 +655,11 @@ static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
return PCIBIOS_DEVICE_NOT_FOUND; return PCIBIOS_DEVICE_NOT_FOUND;
} }
spin_lock_irqsave(&pp->conf_lock, flags);
if (bus->number != pp->root_bus_nr) if (bus->number != pp->root_bus_nr)
ret = dw_pcie_rd_other_conf(pp, bus, devfn, ret = dw_pcie_rd_other_conf(pp, bus, devfn,
where, size, val); where, size, val);
else else
ret = dw_pcie_rd_own_conf(pp, where, size, val); ret = dw_pcie_rd_own_conf(pp, where, size, val);
spin_unlock_irqrestore(&pp->conf_lock, flags);
return ret; return ret;
} }
...@@ -670,7 +668,6 @@ static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn, ...@@ -670,7 +668,6 @@ static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
int where, int size, u32 val) int where, int size, u32 val)
{ {
struct pcie_port *pp = sys_to_pcie(bus->sysdata); struct pcie_port *pp = sys_to_pcie(bus->sysdata);
unsigned long flags;
int ret; int ret;
if (!pp) { if (!pp) {
...@@ -681,13 +678,11 @@ static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn, ...@@ -681,13 +678,11 @@ static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0)
return PCIBIOS_DEVICE_NOT_FOUND; return PCIBIOS_DEVICE_NOT_FOUND;
spin_lock_irqsave(&pp->conf_lock, flags);
if (bus->number != pp->root_bus_nr) if (bus->number != pp->root_bus_nr)
ret = dw_pcie_wr_other_conf(pp, bus, devfn, ret = dw_pcie_wr_other_conf(pp, bus, devfn,
where, size, val); where, size, val);
else else
ret = dw_pcie_wr_own_conf(pp, where, size, val); ret = dw_pcie_wr_own_conf(pp, where, size, val);
spin_unlock_irqrestore(&pp->conf_lock, flags);
return ret; return ret;
} }
...@@ -727,7 +722,7 @@ static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data *sys) ...@@ -727,7 +722,7 @@ static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data *sys)
if (pp) { if (pp) {
pp->root_bus_nr = sys->busnr; pp->root_bus_nr = sys->busnr;
bus = pci_scan_root_bus(NULL, sys->busnr, &dw_pcie_ops, bus = pci_scan_root_bus(pp->dev, sys->busnr, &dw_pcie_ops,
sys, &sys->resources); sys, &sys->resources);
} else { } else {
bus = NULL; bus = NULL;
...@@ -740,8 +735,13 @@ static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data *sys) ...@@ -740,8 +735,13 @@ static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data *sys)
static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
{ {
struct pcie_port *pp = sys_to_pcie(dev->bus->sysdata); struct pcie_port *pp = sys_to_pcie(dev->bus->sysdata);
int irq;
irq = of_irq_parse_and_map_pci(dev, slot, pin);
if (!irq)
irq = pp->irq;
return pp->irq; return irq;
} }
static void dw_pcie_add_bus(struct pci_bus *bus) static void dw_pcie_add_bus(struct pci_bus *bus)
...@@ -768,7 +768,7 @@ void dw_pcie_setup_rc(struct pcie_port *pp) ...@@ -768,7 +768,7 @@ void dw_pcie_setup_rc(struct pcie_port *pp)
u32 membase; u32 membase;
u32 memlimit; u32 memlimit;
/* set the number of lines as 4 */ /* set the number of lanes */
dw_pcie_readl_rc(pp, PCIE_PORT_LINK_CONTROL, &val); dw_pcie_readl_rc(pp, PCIE_PORT_LINK_CONTROL, &val);
val &= ~PORT_LINK_MODE_MASK; val &= ~PORT_LINK_MODE_MASK;
switch (pp->lanes) { switch (pp->lanes) {
......
...@@ -41,7 +41,6 @@ struct pcie_port { ...@@ -41,7 +41,6 @@ struct pcie_port {
void __iomem *va_cfg1_base; void __iomem *va_cfg1_base;
u64 io_base; u64 io_base;
u64 mem_base; u64 mem_base;
spinlock_t conf_lock;
struct resource cfg; struct resource cfg;
struct resource io; struct resource io;
struct resource mem; struct resource mem;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment