Author: mw
Date: Wed Apr  4 12:41:42 2018
New Revision: 332015
URL: https://svnweb.freebsd.org/changeset/base/332015

Log:
  Match Marvell Armada38X PCI compatible with Linux
  
  In Linux FDT pcie does not have compatible string.
  Configuration of windows in mv_common was based on fdt compatible.
  Now pcie windows are configured by their parent: pcie_controller.
  Processing is moved to fdt_win_process_child. fdt_win_process now
  only walk through the tree. SOC_NODE_PCI is position of pcie function in
  soc_node_spec array.
  
  PCIe probe cannot use ofw_bus_search_compatible, because it needs to
  check also device type and parents compatible.
  
  Submitted by: Rafal Kozik <r...@semihalf.com>
  Reviewed by: manu [DT part]
  Obtained from: Semihalf
  Sponsored by: Stormshield
  Differential Revision: https://reviews.freebsd.org/D14749

Modified:
  head/sys/arm/mv/mv_common.c
  head/sys/arm/mv/mv_pci.c
  head/sys/dts/arm/armada-380.dtsi
  head/sys/dts/arm/armada-385.dtsi

Modified: head/sys/arm/mv/mv_common.c
==============================================================================
--- head/sys/arm/mv/mv_common.c Wed Apr  4 12:36:55 2018        (r332014)
+++ head/sys/arm/mv/mv_common.c Wed Apr  4 12:41:42 2018        (r332015)
@@ -76,6 +76,8 @@ MALLOC_DEFINE(M_IDMA, "idma", "idma dma test memory");
 #define MV_DUMP_WIN    0
 #endif
 
+struct soc_node_spec;
+
 static enum soc_family soc_family;
 
 static int mv_win_cesa_attr(int wng_sel);
@@ -174,6 +176,8 @@ int gic_decode_fdt(phandle_t iparent, pcell_t *intr, i
 static int win_cpu_from_dt(void);
 static int fdt_win_setup(void);
 
+static int fdt_win_process_child(phandle_t, struct soc_node_spec *);
+
 static uint32_t dev_mask = 0;
 static int cpu_wins_no = 0;
 static int eth_port = 0;
@@ -225,6 +229,8 @@ static struct soc_node_spec soc_nodes[] = {
        { NULL, NULL, NULL, NULL },
 };
 
+#define        SOC_NODE_PCIE_ENTRY_IDX         11
+
 typedef uint32_t(*read_cpu_ctrl_t)(uint32_t);
 typedef void(*write_cpu_ctrl_t)(uint32_t, uint32_t);
 typedef uint32_t (*win_read_t)(int);
@@ -2741,55 +2747,63 @@ moveon:
 static int
 fdt_win_process(phandle_t child)
 {
-       int i;
-       struct soc_node_spec *soc_node;
-       int addr_cells, size_cells;
-       pcell_t reg[8];
-       u_long size, base;
+       int i, ret;
 
        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))
+               if (!ofw_bus_node_is_compatible(child, soc_nodes[i].compat))
                        continue;
 
-               if (fdt_addrsize_cells(OF_parent(child), &addr_cells,
-                   &size_cells))
-                       return (ENXIO);
+               ret = fdt_win_process_child(child, &soc_nodes[i]);
+               if (ret != 0)
+                       return (ret);
+       }
 
-               if ((sizeof(pcell_t) * (addr_cells + size_cells)) > sizeof(reg))
-                       return (ENOMEM);
+       return (0);
+}
 
-               if (OF_getprop(child, "reg", &reg, sizeof(reg)) <= 0)
-                       return (EINVAL);
+static int
+fdt_win_process_child(phandle_t child, struct soc_node_spec *soc_node)
+{
+       int addr_cells, size_cells;
+       pcell_t reg[8];
+       u_long size, base;
 
-               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);
+       if (fdt_addrsize_cells(OF_parent(child), &addr_cells,
+           &size_cells))
+               return (ENXIO);
 
-               if (soc_node->valid_handler != NULL)
-                       if (!soc_node->valid_handler())
-                               return (EINVAL);
+       if ((sizeof(pcell_t) * (addr_cells + size_cells)) > sizeof(reg))
+               return (ENOMEM);
 
-               base = (base & 0x000fffff) | fdt_immr_va;
-               if (soc_node->decode_handler != NULL)
-                       soc_node->decode_handler(base);
-               else
-                       return (ENXIO);
+       if (OF_getprop(child, "reg", &reg, sizeof(reg)) <= 0)
+               return (EINVAL);
 
-               if (MV_DUMP_WIN && (soc_node->dump_handler != NULL))
-                       soc_node->dump_handler(base);
-       }
+       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);
 
+       if (soc_node->valid_handler != NULL)
+               if (!soc_node->valid_handler())
+                       return (EINVAL);
+
+       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)
 {
@@ -2821,7 +2835,8 @@ fdt_win_setup(void)
                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);
+                               err = fdt_win_process_child(child_pci,
+                                   &soc_nodes[SOC_NODE_PCIE_ENTRY_IDX]);
                                if (err != 0)
                                        return (err);
 

Modified: head/sys/arm/mv/mv_pci.c
==============================================================================
--- head/sys/arm/mv/mv_pci.c    Wed Apr  4 12:36:55 2018        (r332014)
+++ head/sys/arm/mv/mv_pci.c    Wed Apr  4 12:41:42 2018        (r332015)
@@ -413,7 +413,9 @@ mv_pcib_probe(device_t self)
                return (ENXIO);
 
        if (!(ofw_bus_is_compatible(self, "mrvl,pcie") ||
-           ofw_bus_is_compatible(self, "mrvl,pci")))
+           ofw_bus_is_compatible(self, "mrvl,pci") ||
+           ofw_bus_node_is_compatible(
+           OF_parent(node), "marvell,armada-370-pcie")))
                return (ENXIO);
 
        device_set_desc(self, "Marvell Integrated PCI/PCI-E Controller");
@@ -447,19 +449,18 @@ mv_pcib_attach(device_t self)
 
        if (ofw_bus_node_is_compatible(node, "mrvl,pcie")) {
                sc->sc_type = MV_TYPE_PCIE;
-               if (ofw_bus_node_is_compatible(parnode, 
"marvell,armada-370-pcie")) {
-                       sc->sc_win_target = 
MV_WIN_PCIE_TARGET_ARMADA38X(port_id);
-                       sc->sc_mem_win_attr = 
MV_WIN_PCIE_MEM_ATTR_ARMADA38X(port_id);
-                       sc->sc_io_win_attr = 
MV_WIN_PCIE_IO_ATTR_ARMADA38X(port_id);
-                       sc->sc_enable_find_root_slot = 1;
-               } else {
-                       sc->sc_win_target = MV_WIN_PCIE_TARGET(port_id);
-                       sc->sc_mem_win_attr = MV_WIN_PCIE_MEM_ATTR(port_id);
-                       sc->sc_io_win_attr = MV_WIN_PCIE_IO_ATTR(port_id);
+               sc->sc_win_target = MV_WIN_PCIE_TARGET(port_id);
+               sc->sc_mem_win_attr = MV_WIN_PCIE_MEM_ATTR(port_id);
+               sc->sc_io_win_attr = MV_WIN_PCIE_IO_ATTR(port_id);
 #if __ARM_ARCH >= 6
-                       sc->sc_skip_enable_procedure = 1;
+               sc->sc_skip_enable_procedure = 1;
 #endif
-               }
+       } else if (ofw_bus_node_is_compatible(parnode, 
"marvell,armada-370-pcie")) {
+               sc->sc_type = MV_TYPE_PCIE;
+               sc->sc_win_target = MV_WIN_PCIE_TARGET_ARMADA38X(port_id);
+               sc->sc_mem_win_attr = MV_WIN_PCIE_MEM_ATTR_ARMADA38X(port_id);
+               sc->sc_io_win_attr = MV_WIN_PCIE_IO_ATTR_ARMADA38X(port_id);
+               sc->sc_enable_find_root_slot = 1;
        } else if (ofw_bus_node_is_compatible(node, "mrvl,pci")) {
                sc->sc_type = MV_TYPE_PCI;
                sc->sc_win_target = MV_WIN_PCI_TARGET;

Modified: head/sys/dts/arm/armada-380.dtsi
==============================================================================
--- head/sys/dts/arm/armada-380.dtsi    Wed Apr  4 12:36:55 2018        
(r332014)
+++ head/sys/dts/arm/armada-380.dtsi    Wed Apr  4 12:41:42 2018        
(r332015)
@@ -98,7 +98,6 @@
 
                        /* x1 port */
                        pcie@1,0 {
-                               compatible = "mrvl,pcie";
                                device_type = "pci";
                                assigned-addresses = <0x82000800 0 0x80000 0 
0x2000>;
                                reg = <0x0 0x0 0x80000 0x0 0x2000>;
@@ -119,7 +118,6 @@
 
                        /* x1 port */
                        pcie@2,0 {
-                               compatible = "mrvl,pcie";
                                device_type = "pci";
                                assigned-addresses = <0x82000800 0 0x40000 0 
0x2000>;
                                reg = <0x0 0x0 0x40000 0x0 0x2000>;
@@ -140,7 +138,6 @@
 
                        /* x1 port */
                        pcie@3,0 {
-                               compatible = "mrvl,pcie";
                                device_type = "pci";
                                assigned-addresses = <0x82000800 0 0x44000 0 
0x2000>;
                                reg = <0x0 0x0 0x44000 0x0 0x2000>;

Modified: head/sys/dts/arm/armada-385.dtsi
==============================================================================
--- head/sys/dts/arm/armada-385.dtsi    Wed Apr  4 12:36:55 2018        
(r332014)
+++ head/sys/dts/arm/armada-385.dtsi    Wed Apr  4 12:41:42 2018        
(r332015)
@@ -110,7 +110,6 @@
                         * pcie@4,0 is not available.
                         */
                        pcie@1,0 {
-                               compatible = "mrvl,pcie";
                                device_type = "pci";
                                assigned-addresses = <0x82000800 0 0x80000 0 
0x2000>;
                                reg = <0x0 0x0 0x80000 0x0 0x2000>;
@@ -131,7 +130,6 @@
 
                        /* x1 port */
                        pcie@2,0 {
-                               compatible = "mrvl,pcie";
                                device_type = "pci";
                                assigned-addresses = <0x82000800 0 0x40000 0 
0x2000>;
                                reg = <0x0 0x0 0x40000 0x0 0x2000>;
@@ -152,7 +150,6 @@
 
                        /* x1 port */
                        pcie@3,0 {
-                               compatible = "mrvl,pcie";
                                device_type = "pci";
                                assigned-addresses = <0x82000800 0 0x44000 0 
0x2000>;
                                reg = <0x0 0x0 0x44000 0x0 0x2000>;
@@ -176,7 +173,6 @@
                         * configured as a x1 port
                         */
                        pcie@4,0 {
-                               compatible = "mrvl,pcie";
                                device_type = "pci";
                                assigned-addresses = <0x82000800 0 0x48000 0 
0x2000>;
                                reg = <0x0 0x0 0x48000 0x0 0x2000>;
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to