-static int tegra_pcie_parse_dt_ranges(const void *fdt, int node,
- struct tegra_pcie *pcie)
-{
- int parent, na_parent, na_pcie, ns_pcie;
- const u32 *ptr, *end;
- int len;
-
- parent = fdt_parent_offset(fdt, node);
- if (parent < 0) {
- error("Can't find PCI parent node\n");
- return -FDT_ERR_NOTFOUND;
- }
-
- na_parent = fdt_address_cells(fdt, parent);
- if (na_parent < 1) {
- error("bad #address-cells for PCIE parent\n");
- return -FDT_ERR_NOTFOUND;
- }
-
- na_pcie = fdt_address_cells(fdt, node);
- if (na_pcie < 1) {
- error("bad #address-cells for PCIE\n");
- return -FDT_ERR_NOTFOUND;
- }
-
- ns_pcie = fdt_size_cells(fdt, node);
- if (ns_pcie < 1) {
- error("bad #size-cells for PCIE\n");
- return -FDT_ERR_NOTFOUND;
- }
-
- ptr = fdt_getprop(fdt, node, "ranges", &len);
- if (!ptr) {
- error("missing \"ranges\" property");
- return -FDT_ERR_NOTFOUND;
- }
-
- end = ptr + len / 4;
-
- while (ptr < end) {
- struct fdt_resource *res = NULL;
- u32 space = fdt32_to_cpu(*ptr);
-
- switch ((space >> 24) & 0x3) {
- case 0x01:
- res = &pcie->io;
- break;
-
- case 0x02: /* 32 bit */
- case 0x03: /* 64 bit */
- if (space & (1 << 30))
- res = &pcie->prefetch;
- else
- res = &pcie->mem;
-
- break;
- }
-
- if (res) {
- int start_low = na_pcie + (na_parent - 1);
- int size_low = na_pcie + na_parent + (ns_pcie - 1);
- res->start = fdt32_to_cpu(ptr[start_low]);
- res->end = res->start + fdt32_to_cpu(ptr[size_low]);
- }
-
- ptr += na_pcie + na_parent + ns_pcie;
- }
-
- debug("PCI regions:\n");
- debug(" I/O: %pa-%pa\n", &pcie->io.start, &pcie->io.end);
- debug(" non-prefetchable memory: %pa-%pa\n", &pcie->mem.start,
- &pcie->mem.end);
- debug(" prefetchable memory: %pa-%pa\n", &pcie->prefetch.start,
- &pcie->prefetch.end);
-
- return 0;
-}
-