svn commit: r319705 - head/sys/arm/mv
Zbigniew Bodek
zbb at FreeBSD.org
Thu Jun 8 16:51:48 UTC 2017
Author: zbb
Date: Thu Jun 8 16:51:46 2017
New Revision: 319705
URL: https://svnweb.freebsd.org/changeset/base/319705
Log:
Fix PCIe window decoding on Armada 38x
Original PCIe nodes for Marvell SoCs consists of ports' nodes
under main controller node. In order to properly parse
this kind of representation in DT a mechanism for traversing
through the tree required an update. Moreover, processing FDT
data consisting of more than 2 cells had to be fixed,
because the 'reg' property of mrvl,pcie node have additional
parameter in front of 64-bit address. It should be skipped
by default. This commit works properly with old mrvl,pcie
representation for Kirkwood and ArmadaXP SoCs.
Submitted by: Wojciech Macek <wma at semihalf.com>
Michal Mazur <mkm at semihalf.com>
Obtained from: Semihalf
Sponsored by: Stormshield, Netgate
Differential revision: https://reviews.freebsd.org/D10905
Modified:
head/sys/arm/mv/mv_common.c
Modified: head/sys/arm/mv/mv_common.c
==============================================================================
--- head/sys/arm/mv/mv_common.c Thu Jun 8 16:48:09 2017 (r319704)
+++ head/sys/arm/mv/mv_common.c Thu Jun 8 16:51:46 2017 (r319705)
@@ -2380,13 +2380,60 @@ moveon:
}
static int
-fdt_win_setup(void)
+fdt_win_process(phandle_t child)
{
- phandle_t node, child, sb;
+ int i;
struct soc_node_spec *soc_node;
+ int addr_cells, size_cells;
+ pcell_t reg[8];
u_long size, base;
- int err, i;
+ for (i = 0; soc_nodes[i].compat != NULL; i++) {
+
+ soc_node = &soc_nodes[i];
+
+ /* Setup only for enabled devices */
+ if (ofw_bus_node_status_okay(child) == 0)
+ continue;
+
+ if (!ofw_bus_node_is_compatible(child, soc_node->compat))
+ continue;
+
+ if (fdt_addrsize_cells(OF_parent(child), &addr_cells,
+ &size_cells))
+ return (ENXIO);
+
+ if ((sizeof(pcell_t) * (addr_cells + size_cells)) > sizeof(reg))
+ return (ENOMEM);
+
+ if (OF_getprop(child, "reg", ®, sizeof(reg)) <= 0)
+ return (EINVAL);
+
+ if (addr_cells <= 2)
+ base = fdt_data_get(®[0], addr_cells);
+ else
+ base = fdt_data_get(®[addr_cells - 2], 2);
+ size = fdt_data_get(®[addr_cells], size_cells);
+
+ base = (base & 0x000fffff) | fdt_immr_va;
+ if (soc_node->decode_handler != NULL)
+ soc_node->decode_handler(base);
+ else
+ return (ENXIO);
+
+ if (MV_DUMP_WIN && (soc_node->dump_handler != NULL))
+ soc_node->dump_handler(base);
+ }
+
+ return (0);
+}
+static int
+fdt_win_setup(void)
+{
+ phandle_t node, child, sb;
+ phandle_t child_pci;
+ int err;
+
sb = 0;
node = OF_finddevice("/");
if (node == -1)
@@ -2398,29 +2445,21 @@ fdt_win_setup(void)
*/
child = OF_child(node);
while (child != 0) {
- for (i = 0; soc_nodes[i].compat != NULL; i++) {
+ /* Lookup for callback and run */
+ err = fdt_win_process(child);
+ if (err != 0)
+ return (err);
- soc_node = &soc_nodes[i];
+ /* Process Marvell Armada-XP/38x PCIe controllers */
+ if (ofw_bus_node_is_compatible(child, "marvell,armada-370-pcie")) {
+ child_pci = OF_child(child);
+ while (child_pci != 0) {
+ err = fdt_win_process(child_pci);
+ if (err != 0)
+ return (err);
- /* Setup only for enabled devices */
- if (ofw_bus_node_status_okay(child) == 0)
- continue;
-
- if (!ofw_bus_node_is_compatible(child,soc_node->compat))
- continue;
-
- err = fdt_regsize(child, &base, &size);
- if (err != 0)
- return (err);
-
- base = (base & 0x000fffff) | fdt_immr_va;
- if (soc_node->decode_handler != NULL)
- soc_node->decode_handler(base);
- else
- return (ENXIO);
-
- if (MV_DUMP_WIN && (soc_node->dump_handler != NULL))
- soc_node->dump_handler(base);
+ child_pci = OF_peer(child_pci);
+ }
}
/*
More information about the svn-src-all
mailing list