aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/host
diff options
context:
space:
mode:
authorOlof Johansson <olof@lixom.net>2013-08-16 02:10:31 -0400
committerOlof Johansson <olof@lixom.net>2013-08-16 02:10:31 -0400
commitf668adebf43556df9834f254479a44a20294dcf1 (patch)
tree1db70c6f513da3c4c2fdc0341ef0d8ffdffa07f5 /drivers/pci/host
parentfac2e57742d9aa3dbe41860280352efda9d5566e (diff)
parenta0cec7867ffdf5d153d29b3a8243911ea8dfd366 (diff)
Merge tag 'drivers-3.12' of git://git.infradead.org/linux-mvebu into next/soc
From Jason Cooper: mvebu drivers changes for v3.12 - MBus devicetree bindings - devbus update for address decoding window, cleanup * tag 'drivers-3.12' of git://git.infradead.org/linux-mvebu: (35 commits) memory: mvebu-devbus: Remove unused variable ARM: mvebu: Relocate PCIe node in Armada 370 RD board ARM: mvebu: Fix AXP-WiFi-AP DT for MBUS DT binding ARM: mvebu: add support for the AXP WiFi AP board ARM: mvebu: use dts pre-processor for mv78230 PCI: mvebu: Adapt to the new device tree layout bus: mvebu-mbus: Add devicetree binding ARM: kirkwood: Relocate PCIe device tree nodes ARM: kirkwood: Introduce MBUS_ID ARM: kirkwood: Introduce MBus DT node ARM: kirkwood: Use the preprocessor on device tree files ARM: kirkwood: Split DT and legacy MBus initialization ARM: mvebu: Relocate Armada 370/XP PCIe device tree nodes ARM: mvebu: Relocate Armada 370/XP DeviceBus device tree nodes ARM: mvebu: Add BootROM to Armada 370/XP device tree ARM: mvebu: Add MBus to Armada 370/XP device tree ARM: mvebu: Use the preprocessor on Armada 370/XP device tree files ARM: mvebu: Initialize MBus using the DT binding ARM: mvebu: Remove the harcoded BootROM window allocation bus: mvebu-mbus: Factorize Armada 370/XP data structures ... Signed-off-by: Olof Johansson <olof@lixom.net>
Diffstat (limited to 'drivers/pci/host')
-rw-r--r--drivers/pci/host/pci-mvebu.c115
1 files changed, 86 insertions, 29 deletions
diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c
index 13a633b1612e..338691b616d9 100644
--- a/drivers/pci/host/pci-mvebu.c
+++ b/drivers/pci/host/pci-mvebu.c
@@ -123,6 +123,10 @@ struct mvebu_pcie_port {
123 u32 port; 123 u32 port;
124 u32 lane; 124 u32 lane;
125 int devfn; 125 int devfn;
126 unsigned int mem_target;
127 unsigned int mem_attr;
128 unsigned int io_target;
129 unsigned int io_attr;
126 struct clk *clk; 130 struct clk *clk;
127 struct mvebu_sw_pci_bridge bridge; 131 struct mvebu_sw_pci_bridge bridge;
128 struct device_node *dn; 132 struct device_node *dn;
@@ -307,10 +311,9 @@ static void mvebu_pcie_handle_iobase_change(struct mvebu_pcie_port *port)
307 (port->bridge.iolimitupper << 16)) - 311 (port->bridge.iolimitupper << 16)) -
308 iobase); 312 iobase);
309 313
310 mvebu_mbus_add_window_remap_flags(port->name, port->iowin_base, 314 mvebu_mbus_add_window_remap_by_id(port->io_target, port->io_attr,
311 port->iowin_size, 315 port->iowin_base, port->iowin_size,
312 iobase, 316 iobase);
313 MVEBU_MBUS_PCI_IO);
314 317
315 pci_ioremap_io(iobase, port->iowin_base); 318 pci_ioremap_io(iobase, port->iowin_base);
316} 319}
@@ -342,10 +345,8 @@ static void mvebu_pcie_handle_membase_change(struct mvebu_pcie_port *port)
342 (((port->bridge.memlimit & 0xFFF0) << 16) | 0xFFFFF) - 345 (((port->bridge.memlimit & 0xFFF0) << 16) | 0xFFFFF) -
343 port->memwin_base; 346 port->memwin_base;
344 347
345 mvebu_mbus_add_window_remap_flags(port->name, port->memwin_base, 348 mvebu_mbus_add_window_by_id(port->mem_target, port->mem_attr,
346 port->memwin_size, 349 port->memwin_base, port->memwin_size);
347 MVEBU_MBUS_NO_REMAP,
348 MVEBU_MBUS_PCI_MEM);
349} 350}
350 351
351/* 352/*
@@ -661,6 +662,8 @@ static int __init mvebu_pcie_setup(int nr, struct pci_sys_data *sys)
661 662
662 for (i = 0; i < pcie->nports; i++) { 663 for (i = 0; i < pcie->nports; i++) {
663 struct mvebu_pcie_port *port = &pcie->ports[i]; 664 struct mvebu_pcie_port *port = &pcie->ports[i];
665 if (!port->base)
666 continue;
664 mvebu_pcie_setup_hw(port); 667 mvebu_pcie_setup_hw(port);
665 } 668 }
666 669
@@ -755,12 +758,54 @@ mvebu_pcie_map_registers(struct platform_device *pdev,
755 return devm_request_and_ioremap(&pdev->dev, &regs); 758 return devm_request_and_ioremap(&pdev->dev, &regs);
756} 759}
757 760
761#define DT_FLAGS_TO_TYPE(flags) (((flags) >> 24) & 0x03)
762#define DT_TYPE_IO 0x1
763#define DT_TYPE_MEM32 0x2
764#define DT_CPUADDR_TO_TARGET(cpuaddr) (((cpuaddr) >> 56) & 0xFF)
765#define DT_CPUADDR_TO_ATTR(cpuaddr) (((cpuaddr) >> 48) & 0xFF)
766
767static int mvebu_get_tgt_attr(struct device_node *np, int devfn,
768 unsigned long type, int *tgt, int *attr)
769{
770 const int na = 3, ns = 2;
771 const __be32 *range;
772 int rlen, nranges, rangesz, pna, i;
773
774 range = of_get_property(np, "ranges", &rlen);
775 if (!range)
776 return -EINVAL;
777
778 pna = of_n_addr_cells(np);
779 rangesz = pna + na + ns;
780 nranges = rlen / sizeof(__be32) / rangesz;
781
782 for (i = 0; i < nranges; i++) {
783 u32 flags = of_read_number(range, 1);
784 u32 slot = of_read_number(range, 2);
785 u64 cpuaddr = of_read_number(range + na, pna);
786 unsigned long rtype;
787
788 if (DT_FLAGS_TO_TYPE(flags) == DT_TYPE_IO)
789 rtype = IORESOURCE_IO;
790 else if (DT_FLAGS_TO_TYPE(flags) == DT_TYPE_MEM32)
791 rtype = IORESOURCE_MEM;
792
793 if (slot == PCI_SLOT(devfn) && type == rtype) {
794 *tgt = DT_CPUADDR_TO_TARGET(cpuaddr);
795 *attr = DT_CPUADDR_TO_ATTR(cpuaddr);
796 return 0;
797 }
798
799 range += rangesz;
800 }
801
802 return -ENOENT;
803}
804
758static int __init mvebu_pcie_probe(struct platform_device *pdev) 805static int __init mvebu_pcie_probe(struct platform_device *pdev)
759{ 806{
760 struct mvebu_pcie *pcie; 807 struct mvebu_pcie *pcie;
761 struct device_node *np = pdev->dev.of_node; 808 struct device_node *np = pdev->dev.of_node;
762 struct of_pci_range range;
763 struct of_pci_range_parser parser;
764 struct device_node *child; 809 struct device_node *child;
765 int i, ret; 810 int i, ret;
766 811
@@ -771,29 +816,25 @@ static int __init mvebu_pcie_probe(struct platform_device *pdev)
771 816
772 pcie->pdev = pdev; 817 pcie->pdev = pdev;
773 818
774 if (of_pci_range_parser_init(&parser, np)) 819 /* Get the PCIe memory and I/O aperture */
820 mvebu_mbus_get_pcie_mem_aperture(&pcie->mem);
821 if (resource_size(&pcie->mem) == 0) {
822 dev_err(&pdev->dev, "invalid memory aperture size\n");
775 return -EINVAL; 823 return -EINVAL;
824 }
776 825
777 /* Get the I/O and memory ranges from DT */ 826 mvebu_mbus_get_pcie_io_aperture(&pcie->io);
778 for_each_of_pci_range(&parser, &range) { 827 if (resource_size(&pcie->io) == 0) {
779 unsigned long restype = range.flags & IORESOURCE_TYPE_BITS; 828 dev_err(&pdev->dev, "invalid I/O aperture size\n");
780 if (restype == IORESOURCE_IO) { 829 return -EINVAL;
781 of_pci_range_to_resource(&range, np, &pcie->io);
782 of_pci_range_to_resource(&range, np, &pcie->realio);
783 pcie->io.name = "I/O";
784 pcie->realio.start = max_t(resource_size_t,
785 PCIBIOS_MIN_IO,
786 range.pci_addr);
787 pcie->realio.end = min_t(resource_size_t,
788 IO_SPACE_LIMIT,
789 range.pci_addr + range.size);
790 }
791 if (restype == IORESOURCE_MEM) {
792 of_pci_range_to_resource(&range, np, &pcie->mem);
793 pcie->mem.name = "MEM";
794 }
795 } 830 }
796 831
832 pcie->realio.flags = pcie->io.flags;
833 pcie->realio.start = PCIBIOS_MIN_IO;
834 pcie->realio.end = min_t(resource_size_t,
835 IO_SPACE_LIMIT,
836 resource_size(&pcie->io));
837
797 /* Get the bus range */ 838 /* Get the bus range */
798 ret = of_pci_parse_bus_range(np, &pcie->busn); 839 ret = of_pci_parse_bus_range(np, &pcie->busn);
799 if (ret) { 840 if (ret) {
@@ -841,6 +882,22 @@ static int __init mvebu_pcie_probe(struct platform_device *pdev)
841 if (port->devfn < 0) 882 if (port->devfn < 0)
842 continue; 883 continue;
843 884
885 ret = mvebu_get_tgt_attr(np, port->devfn, IORESOURCE_MEM,
886 &port->mem_target, &port->mem_attr);
887 if (ret < 0) {
888 dev_err(&pdev->dev, "PCIe%d.%d: cannot get tgt/attr for mem window\n",
889 port->port, port->lane);
890 continue;
891 }
892
893 ret = mvebu_get_tgt_attr(np, port->devfn, IORESOURCE_IO,
894 &port->io_target, &port->io_attr);
895 if (ret < 0) {
896 dev_err(&pdev->dev, "PCIe%d.%d: cannot get tgt/attr for io window\n",
897 port->port, port->lane);
898 continue;
899 }
900
844 port->base = mvebu_pcie_map_registers(pdev, child, port); 901 port->base = mvebu_pcie_map_registers(pdev, child, port);
845 if (!port->base) { 902 if (!port->base) {
846 dev_err(&pdev->dev, "PCIe%d.%d: cannot map registers\n", 903 dev_err(&pdev->dev, "PCIe%d.%d: cannot map registers\n",