Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 8 Jun 2017 16:51:47 +0000 (UTC)
From:      Zbigniew Bodek <zbb@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r319705 - head/sys/arm/mv
Message-ID:  <201706081651.v58GplEV079025@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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@semihalf.com>
  		Michal Mazur <mkm@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", &reg, sizeof(reg)) <= 0)
+			return (EINVAL);
+
+		if (addr_cells <= 2)
+			base = fdt_data_get(&reg[0], addr_cells);
+		else
+			base = fdt_data_get(&reg[addr_cells - 2], 2);
+		size = fdt_data_get(&reg[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);
+			}
 		}
 
 		/*



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201706081651.v58GplEV079025>