aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/host/pci-mvebu.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/host/pci-mvebu.c')
-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 ce1543a584a3..729d5a101d62 100644
--- a/drivers/pci/host/pci-mvebu.c
+++ b/drivers/pci/host/pci-mvebu.c
@@ -119,6 +119,10 @@ struct mvebu_pcie_port {
119 u32 port; 119 u32 port;
120 u32 lane; 120 u32 lane;
121 int devfn; 121 int devfn;
122 unsigned int mem_target;
123 unsigned int mem_attr;
124 unsigned int io_target;
125 unsigned int io_attr;
122 struct clk *clk; 126 struct clk *clk;
123 struct mvebu_sw_pci_bridge bridge; 127 struct mvebu_sw_pci_bridge bridge;
124 struct device_node *dn; 128 struct device_node *dn;
@@ -303,10 +307,9 @@ static void mvebu_pcie_handle_iobase_change(struct mvebu_pcie_port *port)
303 (port->bridge.iolimitupper << 16)) - 307 (port->bridge.iolimitupper << 16)) -
304 iobase); 308 iobase);
305 309
306 mvebu_mbus_add_window_remap_flags(port->name, port->iowin_base, 310 mvebu_mbus_add_window_remap_by_id(port->io_target, port->io_attr,
307 port->iowin_size, 311 port->iowin_base, port->iowin_size,
308 iobase, 312 iobase);
309 MVEBU_MBUS_PCI_IO);
310 313
311 pci_ioremap_io(iobase, port->iowin_base); 314 pci_ioremap_io(iobase, port->iowin_base);
312} 315}
@@ -338,10 +341,8 @@ static void mvebu_pcie_handle_membase_change(struct mvebu_pcie_port *port)
338 (((port->bridge.memlimit & 0xFFF0) << 16) | 0xFFFFF) - 341 (((port->bridge.memlimit & 0xFFF0) << 16) | 0xFFFFF) -
339 port->memwin_base; 342 port->memwin_base;
340 343
341 mvebu_mbus_add_window_remap_flags(port->name, port->memwin_base, 344 mvebu_mbus_add_window_by_id(port->mem_target, port->mem_attr,
342 port->memwin_size, 345 port->memwin_base, port->memwin_size);
343 MVEBU_MBUS_NO_REMAP,
344 MVEBU_MBUS_PCI_MEM);
345} 346}
346 347
347/* 348/*
@@ -636,6 +637,8 @@ static int __init mvebu_pcie_setup(int nr, struct pci_sys_data *sys)
636 637
637 for (i = 0; i < pcie->nports; i++) { 638 for (i = 0; i < pcie->nports; i++) {
638 struct mvebu_pcie_port *port = &pcie->ports[i]; 639 struct mvebu_pcie_port *port = &pcie->ports[i];
640 if (!port->base)
641 continue;
639 mvebu_pcie_setup_hw(port); 642 mvebu_pcie_setup_hw(port);
640 } 643 }
641 644
@@ -730,12 +733,54 @@ mvebu_pcie_map_registers(struct platform_device *pdev,
730 return devm_ioremap_resource(&pdev->dev, &regs); 733 return devm_ioremap_resource(&pdev->dev, &regs);
731} 734}
732 735
736#define DT_FLAGS_TO_TYPE(flags) (((flags) >> 24) & 0x03)
737#define DT_TYPE_IO 0x1
738#define DT_TYPE_MEM32 0x2
739#define DT_CPUADDR_TO_TARGET(cpuaddr) (((cpuaddr) >> 56) & 0xFF)
740#define DT_CPUADDR_TO_ATTR(cpuaddr) (((cpuaddr) >> 48) & 0xFF)
741
742static int mvebu_get_tgt_attr(struct device_node *np, int devfn,
743 unsigned long type, int *tgt, int *attr)
744{
745 const int na = 3, ns = 2;
746 const __be32 *range;
747 int rlen, nranges, rangesz, pna, i;
748
749 range = of_get_property(np, "ranges", &rlen);
750 if (!range)
751 return -EINVAL;
752
753 pna = of_n_addr_cells(np);
754 rangesz = pna + na + ns;
755 nranges = rlen / sizeof(__be32) / rangesz;
756
757 for (i = 0; i < nranges; i++) {
758 u32 flags = of_read_number(range, 1);
759 u32 slot = of_read_number(range, 2);
760 u64 cpuaddr = of_read_number(range + na, pna);
761 unsigned long rtype;
762
763 if (DT_FLAGS_TO_TYPE(flags) == DT_TYPE_IO)
764 rtype = IORESOURCE_IO;
765 else if (DT_FLAGS_TO_TYPE(flags) == DT_TYPE_MEM32)
766 rtype = IORESOURCE_MEM;
767
768 if (slot == PCI_SLOT(devfn) && type == rtype) {
769 *tgt = DT_CPUADDR_TO_TARGET(cpuaddr);
770 *attr = DT_CPUADDR_TO_ATTR(cpuaddr);
771 return 0;
772 }
773
774 range += rangesz;
775 }
776
777 return -ENOENT;
778}
779
733static int __init mvebu_pcie_probe(struct platform_device *pdev) 780static int __init mvebu_pcie_probe(struct platform_device *pdev)
734{ 781{
735 struct mvebu_pcie *pcie; 782 struct mvebu_pcie *pcie;
736 struct device_node *np = pdev->dev.of_node; 783 struct device_node *np = pdev->dev.of_node;
737 struct of_pci_range range;
738 struct of_pci_range_parser parser;
739 struct device_node *child; 784 struct device_node *child;
740 int i, ret; 785 int i, ret;
741 786
@@ -746,29 +791,25 @@ static int __init mvebu_pcie_probe(struct platform_device *pdev)
746 791
747 pcie->pdev = pdev; 792 pcie->pdev = pdev;
748 793
749 if (of_pci_range_parser_init(&parser, np)) 794 /* Get the PCIe memory and I/O aperture */
795 mvebu_mbus_get_pcie_mem_aperture(&pcie->mem);
796 if (resource_size(&pcie->mem) == 0) {
797 dev_err(&pdev->dev, "invalid memory aperture size\n");
750 return -EINVAL; 798 return -EINVAL;
799 }
751 800
752 /* Get the I/O and memory ranges from DT */ 801 mvebu_mbus_get_pcie_io_aperture(&pcie->io);
753 for_each_of_pci_range(&parser, &range) { 802 if (resource_size(&pcie->io) == 0) {
754 unsigned long restype = range.flags & IORESOURCE_TYPE_BITS; 803 dev_err(&pdev->dev, "invalid I/O aperture size\n");
755 if (restype == IORESOURCE_IO) { 804 return -EINVAL;
756 of_pci_range_to_resource(&range, np, &pcie->io);
757 of_pci_range_to_resource(&range, np, &pcie->realio);
758 pcie->io.name = "I/O";
759 pcie->realio.start = max_t(resource_size_t,
760 PCIBIOS_MIN_IO,
761 range.pci_addr);
762 pcie->realio.end = min_t(resource_size_t,
763 IO_SPACE_LIMIT,
764 range.pci_addr + range.size);
765 }
766 if (restype == IORESOURCE_MEM) {
767 of_pci_range_to_resource(&range, np, &pcie->mem);
768 pcie->mem.name = "MEM";
769 }
770 } 805 }
771 806
807 pcie->realio.flags = pcie->io.flags;
808 pcie->realio.start = PCIBIOS_MIN_IO;
809 pcie->realio.end = min_t(resource_size_t,
810 IO_SPACE_LIMIT,
811 resource_size(&pcie->io));
812
772 /* Get the bus range */ 813 /* Get the bus range */
773 ret = of_pci_parse_bus_range(np, &pcie->busn); 814 ret = of_pci_parse_bus_range(np, &pcie->busn);
774 if (ret) { 815 if (ret) {
@@ -816,6 +857,22 @@ static int __init mvebu_pcie_probe(struct platform_device *pdev)
816 if (port->devfn < 0) 857 if (port->devfn < 0)
817 continue; 858 continue;
818 859
860 ret = mvebu_get_tgt_attr(np, port->devfn, IORESOURCE_MEM,
861 &port->mem_target, &port->mem_attr);
862 if (ret < 0) {
863 dev_err(&pdev->dev, "PCIe%d.%d: cannot get tgt/attr for mem window\n",
864 port->port, port->lane);
865 continue;
866 }
867
868 ret = mvebu_get_tgt_attr(np, port->devfn, IORESOURCE_IO,
869 &port->io_target, &port->io_attr);
870 if (ret < 0) {
871 dev_err(&pdev->dev, "PCIe%d.%d: cannot get tgt/attr for io window\n",
872 port->port, port->lane);
873 continue;
874 }
875
819 port->base = mvebu_pcie_map_registers(pdev, child, port); 876 port->base = mvebu_pcie_map_registers(pdev, child, port);
820 if (IS_ERR(port->base)) { 877 if (IS_ERR(port->base)) {
821 dev_err(&pdev->dev, "PCIe%d.%d: cannot map registers\n", 878 dev_err(&pdev->dev, "PCIe%d.%d: cannot map registers\n",