Skip to content

Commit 11be654

Browse files
tpetazzoniJason Cooper
authored andcommitted
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>
1 parent 79d9468 commit 11be654

File tree

1 file changed

+84
-29
lines changed

1 file changed

+84
-29
lines changed

drivers/pci/host/pci-mvebu.c

Lines changed: 84 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,10 @@ struct mvebu_pcie_port {
123123
u32 port;
124124
u32 lane;
125125
int devfn;
126+
unsigned int mem_target;
127+
unsigned int mem_attr;
128+
unsigned int io_target;
129+
unsigned int io_attr;
126130
struct clk *clk;
127131
struct mvebu_sw_pci_bridge bridge;
128132
struct device_node *dn;
@@ -307,10 +311,9 @@ static void mvebu_pcie_handle_iobase_change(struct mvebu_pcie_port *port)
307311
(port->bridge.iolimitupper << 16)) -
308312
iobase);
309313

310-
mvebu_mbus_add_window_remap_flags(port->name, port->iowin_base,
311-
port->iowin_size,
312-
iobase,
313-
MVEBU_MBUS_PCI_IO);
314+
mvebu_mbus_add_window_remap_by_id(port->io_target, port->io_attr,
315+
port->iowin_base, port->iowin_size,
316+
iobase);
314317

315318
pci_ioremap_io(iobase, port->iowin_base);
316319
}
@@ -342,10 +345,8 @@ static void mvebu_pcie_handle_membase_change(struct mvebu_pcie_port *port)
342345
(((port->bridge.memlimit & 0xFFF0) << 16) | 0xFFFFF) -
343346
port->memwin_base;
344347

345-
mvebu_mbus_add_window_remap_flags(port->name, port->memwin_base,
346-
port->memwin_size,
347-
MVEBU_MBUS_NO_REMAP,
348-
MVEBU_MBUS_PCI_MEM);
348+
mvebu_mbus_add_window_by_id(port->mem_target, port->mem_attr,
349+
port->memwin_base, port->memwin_size);
349350
}
350351

351352
/*
@@ -755,12 +756,54 @@ mvebu_pcie_map_registers(struct platform_device *pdev,
755756
return devm_request_and_ioremap(&pdev->dev, &regs);
756757
}
757758

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+
765+
static 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+
758803
static int __init mvebu_pcie_probe(struct platform_device *pdev)
759804
{
760805
struct mvebu_pcie *pcie;
761806
struct device_node *np = pdev->dev.of_node;
762-
struct of_pci_range range;
763-
struct of_pci_range_parser parser;
764807
struct device_node *child;
765808
int i, ret;
766809

@@ -771,29 +814,25 @@ static int __init mvebu_pcie_probe(struct platform_device *pdev)
771814

772815
pcie->pdev = pdev;
773816

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");
775821
return -EINVAL;
822+
}
776823

777-
/* Get the I/O and memory ranges from DT */
778-
for_each_of_pci_range(&parser, &range) {
779-
unsigned long restype = range.flags & IORESOURCE_TYPE_BITS;
780-
if (restype == IORESOURCE_IO) {
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-
}
824+
mvebu_mbus_get_pcie_io_aperture(&pcie->io);
825+
if (resource_size(&pcie->io) == 0) {
826+
dev_err(&pdev->dev, "invalid I/O aperture size\n");
827+
return -EINVAL;
795828
}
796829

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+
797836
/* Get the bus range */
798837
ret = of_pci_parse_bus_range(np, &pcie->busn);
799838
if (ret) {
@@ -841,6 +880,22 @@ static int __init mvebu_pcie_probe(struct platform_device *pdev)
841880
if (port->devfn < 0)
842881
continue;
843882

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+
844899
port->base = mvebu_pcie_map_registers(pdev, child, port);
845900
if (!port->base) {
846901
dev_err(&pdev->dev, "PCIe%d.%d: cannot map registers\n",

0 commit comments

Comments
 (0)