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 <rk@semihalf.com> Reviewed by: manu [DT part] Obtained from: Semihalf Sponsored by: Stormshield Differential Revision: https://reviews.freebsd.org/D14749
This commit is contained in:
parent
3a582d093b
commit
c7dbc00c34
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=332015
@ -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, int *interrupt,
|
||||
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 @@ win_cpu_from_dt(void)
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
ret = fdt_win_process_child(child, &soc_nodes[i]);
|
||||
if (ret != 0)
|
||||
return (ret);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
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 (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);
|
||||
|
||||
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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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>;
|
||||
|
@ -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>;
|
||||
|
Loading…
Reference in New Issue
Block a user