aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
authorThomas Petazzoni <thomas.petazzoni@free-electrons.com>2013-07-26 09:17:48 -0400
committerJason Cooper <jason@lakedaemon.net>2013-08-06 10:10:38 -0400
commit11be65472a427dcf7a11ab6e3e3628f1c6768b5b (patch)
tree27ebee0bc2ab59ded41a643f9b13ff6c750a208c /drivers/pci
parent79d946837c042fba3e9ba2726f3cfa56aa408e16 (diff)
PCI: mvebu: Adapt to the new device tree layout
The new device tree layout encodes the window's target ID and attribute in the PCIe controller node's ranges property. This allows to parse such entries to obtain such information and use the recently introduced MBus API to create the windows, instead of using the current name based scheme. Acked-by: Bjorn Helgaas <bhelgaas@google.com> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com> Tested-by: Andrew Lunn <andrew@lunn.ch> Tested-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Signed-off-by: Jason Cooper <jason@lakedaemon.net>
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/host/pci-mvebu.c113
1 files changed, 84 insertions, 29 deletions
diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c
index 13a633b1612e..424a7b8e040f 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/*
@@ -755,12 +756,54 @@ mvebu_pcie_map_registers(struct platform_device *pdev,
755 return devm_request_and_ioremap(&pdev->dev, &regs); 756 return devm_request_and_ioremap(&pdev->dev, &regs);
756} 757}
757 758
759#define DT_FLAGS_TO_TYPE(flags) (((flags) >> 24) & 0x03)
760#define DT_TYPE_IO 0x1
761#define DT_TYPE_MEM32 0x2
762#define DT_CPUADDR_TO_TARGET(cpuaddr) (((cpuaddr) >> 56) & 0xFF)
763#define DT_CPUADDR_TO_ATTR(cpuaddr) (((cpuaddr) >> 48) & 0xFF)
764
765static int mvebu_get_tgt_attr(struct device_node *np, int devfn,
766 unsigned long type, int *tgt, int *attr)
767{
768 const int na = 3, ns = 2;
769 const __be32 *range;
770 int rlen, nranges, rangesz, pna, i;
771
772 range = of_get_property(np, "ranges", &rlen);
773 if (!range)
774 return -EINVAL;
775
776 pna = of_n_addr_cells(np);
777 rangesz = pna + na + ns;
778 nranges = rlen / sizeof(__be32) / rangesz;
779
780 for (i = 0; i < nranges; i++) {
781 u32 flags = of_read_number(range, 1);
782 u32 slot = of_read_number(range, 2);
783 u64 cpuaddr = of_read_number(range + na, pna);
784 unsigned long rtype;
785
786 if (DT_FLAGS_TO_TYPE(flags) == DT_TYPE_IO)
787 rtype = IORESOURCE_IO;
788 else if (DT_FLAGS_TO_TYPE(flags) == DT_TYPE_MEM32)
789 rtype = IORESOURCE_MEM;
790
791 if (slot == PCI_SLOT(devfn) && type == rtype) {
792 *tgt = DT_CPUADDR_TO_TARGET(cpuaddr);
793 *attr = DT_CPUADDR_TO_ATTR(cpuaddr);
794 return 0;
795 }
796
797 range += rangesz;
798 }
799
800 return -ENOENT;
801}
802
758static int __init mvebu_pcie_probe(struct platform_device *pdev) 803static int __init mvebu_pcie_probe(struct platform_device *pdev)
759{ 804{
760 struct mvebu_pcie *pcie; 805 struct mvebu_pcie *pcie;
761 struct device_node *np = pdev->dev.of_node; 806 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; 807 struct device_node *child;
765 int i, ret; 808 int i, ret;
766 809
@@ -771,29 +814,25 @@ static int __init mvebu_pcie_probe(struct platform_device *pdev)
771 814
772 pcie->pdev = pdev; 815 pcie->pdev = pdev;
773 816
774 if (of_pci_range_parser_init(&parser, np)) 817 /* Get the PCIe memory and I/O aperture */
818 mvebu_mbus_get_pcie_mem_aperture(&pcie->mem);
819 if (resource_size(&pcie->mem) == 0) {
820 dev_err(&pdev->dev, "invalid memory aperture size\n");
775 return -EINVAL; 821 return -EINVAL;
822 }
776 823
777 /* Get the I/O and memory ranges from DT */ 824 mvebu_mbus_get_pcie_io_aperture(&pcie->io);
778 for_each_of_pci_range(&parser, &range) { 825 if (resource_size(&pcie->io) == 0) {
779 unsigned long restype = range.flags & IORESOURCE_TYPE_BITS; 826 dev_err(&pdev->dev, "invalid I/O aperture size\n");
780 if (restype == IORESOURCE_IO) { 827 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 } 828 }
796 829
830 pcie->realio.flags = pcie->io.flags;
831 pcie->realio.start = PCIBIOS_MIN_IO;
832 pcie->realio.end = min_t(resource_size_t,
833 IO_SPACE_LIMIT,
834 resource_size(&pcie->io));
835
797 /* Get the bus range */ 836 /* Get the bus range */
798 ret = of_pci_parse_bus_range(np, &pcie->busn); 837 ret = of_pci_parse_bus_range(np, &pcie->busn);
799 if (ret) { 838 if (ret) {
@@ -841,6 +880,22 @@ static int __init mvebu_pcie_probe(struct platform_device *pdev)
841 if (port->devfn < 0) 880 if (port->devfn < 0)
842 continue; 881 continue;
843 882
883 ret = mvebu_get_tgt_attr(np, port->devfn, IORESOURCE_MEM,
884 &port->mem_target, &port->mem_attr);
885 if (ret < 0) {
886 dev_err(&pdev->dev, "PCIe%d.%d: cannot get tgt/attr for mem window\n",
887 port->port, port->lane);
888 continue;
889 }
890
891 ret = mvebu_get_tgt_attr(np, port->devfn, IORESOURCE_IO,
892 &port->io_target, &port->io_attr);
893 if (ret < 0) {
894 dev_err(&pdev->dev, "PCIe%d.%d: cannot get tgt/attr for io window\n",
895 port->port, port->lane);
896 continue;
897 }
898
844 port->base = mvebu_pcie_map_registers(pdev, child, port); 899 port->base = mvebu_pcie_map_registers(pdev, child, port);
845 if (!port->base) { 900 if (!port->base) {
846 dev_err(&pdev->dev, "PCIe%d.%d: cannot map registers\n", 901 dev_err(&pdev->dev, "PCIe%d.%d: cannot map registers\n",