fdt_addr_t fdtdec_get_addr_size_fixed(const void *blob, int node, const char *prop_name, int index, int na, int ns, fdt_size_t *sizep, bool translate) { const fdt32_t *prop, *prop_end; const fdt32_t *prop_addr, *prop_size, *prop_after_size; int len; fdt_addr_t addr; debug("%s: %s: ", __func__, prop_name); if (na > (sizeof(fdt_addr_t) / sizeof(fdt32_t))) { debug("(na too large for fdt_addr_t type)\n"); return FDT_ADDR_T_NONE; } if (ns > (sizeof(fdt_size_t) / sizeof(fdt32_t))) { debug("(ns too large for fdt_size_t type)\n"); return FDT_ADDR_T_NONE; } prop = fdt_getprop(blob, node, prop_name, &len); if (!prop) { debug("(not found)\n"); return FDT_ADDR_T_NONE; } prop_end = prop + (len / sizeof(*prop)); prop_addr = prop + (index * (na + ns)); prop_size = prop_addr + na; prop_after_size = prop_size + ns; if (prop_after_size > prop_end) { debug("(not enough data: expected >= %d cells, got %d cells)\n", (u32)(prop_after_size - prop), ((u32)(prop_end - prop))); return FDT_ADDR_T_NONE; } #if CONFIG_IS_ENABLED(OF_TRANSLATE) if (translate) addr = fdt_translate_address(blob, node, prop_addr); else #endif addr = fdtdec_get_number(prop_addr, na); if (sizep) { *sizep = fdtdec_get_number(prop_size, ns); debug("addr=%08llx, size=%llx\n", (unsigned long long)addr, (unsigned long long)*sizep); } else { debug("addr=%08llx\n", (unsigned long long)addr); } return addr; }
int __init early_init_dt_scan_chosen_serial(void) { int offset; const char *p; int l; const struct of_device_id *match = __earlycon_of_table; const void *fdt = initial_boot_params; offset = fdt_path_offset(fdt, "/chosen"); if (offset < 0) offset = fdt_path_offset(fdt, "/chosen@0"); if (offset < 0) return -ENOENT; p = fdt_getprop(fdt, offset, "stdout-path", &l); if (!p) p = fdt_getprop(fdt, offset, "linux,stdout-path", &l); if (!p || !l) return -ENOENT; /* Get the node specified by stdout-path */ offset = fdt_path_offset(fdt, p); if (offset < 0) return -ENODEV; while (match->compatible) { unsigned long addr; if (fdt_node_check_compatible(fdt, offset, match->compatible)) { match++; continue; } addr = fdt_translate_address(fdt, offset); if (!addr) return -ENXIO; of_setup_earlycon(addr, match->data); return 0; } return -ENODEV; }
static int altera_tse_probe(struct udevice *dev) { struct eth_pdata *pdata = dev_get_platdata(dev); struct altera_tse_priv *priv = dev_get_priv(dev); void *blob = (void *)gd->fdt_blob; int node = dev->of_offset; const char *list, *end; const fdt32_t *cell; void *base, *desc_mem = NULL; unsigned long addr, size; int parent, addrc, sizec; int len, idx; int ret; priv->dma_type = dev_get_driver_data(dev); if (priv->dma_type == ALT_SGDMA) priv->ops = &tse_sgdma_ops; else priv->ops = &tse_msgdma_ops; /* * decode regs. there are multiple reg tuples, and they need to * match with reg-names. */ parent = fdt_parent_offset(blob, node); of_bus_default_count_cells(blob, parent, &addrc, &sizec); list = fdt_getprop(blob, node, "reg-names", &len); if (!list) return -ENOENT; end = list + len; cell = fdt_getprop(blob, node, "reg", &len); if (!cell) return -ENOENT; idx = 0; while (list < end) { addr = fdt_translate_address((void *)blob, node, cell + idx); size = fdt_addr_to_cpu(cell[idx + addrc]); base = map_physmem(addr, size, MAP_NOCACHE); len = strlen(list); if (strcmp(list, "control_port") == 0) priv->mac_dev = base; else if (strcmp(list, "rx_csr") == 0) priv->sgdma_rx = base; else if (strcmp(list, "rx_desc") == 0) priv->rx_desc = base; else if (strcmp(list, "rx_resp") == 0) priv->rx_resp = base; else if (strcmp(list, "tx_csr") == 0) priv->sgdma_tx = base; else if (strcmp(list, "tx_desc") == 0) priv->tx_desc = base; else if (strcmp(list, "s1") == 0) desc_mem = base; idx += addrc + sizec; list += (len + 1); } /* decode fifo depth */ priv->rx_fifo_depth = fdtdec_get_int(blob, node, "rx-fifo-depth", 0); priv->tx_fifo_depth = fdtdec_get_int(blob, node, "tx-fifo-depth", 0); /* decode phy */ addr = fdtdec_get_int(blob, node, "phy-handle", 0); addr = fdt_node_offset_by_phandle(blob, addr); priv->phyaddr = fdtdec_get_int(blob, addr, "reg", 0); /* init desc */ if (priv->dma_type == ALT_SGDMA) { len = sizeof(struct alt_sgdma_descriptor) * 4; if (!desc_mem) { desc_mem = dma_alloc_coherent(len, &addr); if (!desc_mem) return -ENOMEM; } memset(desc_mem, 0, len); priv->tx_desc = desc_mem; priv->rx_desc = priv->tx_desc + 2 * sizeof(struct alt_sgdma_descriptor); } /* allocate recv packet buffer */ priv->rx_buf = malloc_cache_aligned(PKTSIZE_ALIGN); if (!priv->rx_buf) return -ENOMEM; /* stop controller */ debug("Reset TSE & SGDMAs\n"); altera_tse_stop(dev); /* start the phy */ priv->interface = pdata->phy_interface; tse_mdio_init(dev->name, priv); priv->bus = miiphy_get_dev_by_name(dev->name); ret = tse_phy_init(priv, dev); return ret; }
void pci_init_board(void) { struct pci_controller *pci_hoses; void *fdt = get_fdt_virt(); int pci_node = -1; int pci_num = 0; int pci_count = 0; ulong map_addr; puts("\n"); /* Start MMIO and PIO range maps above RAM */ map_addr = CONFIG_SYS_PCI_MAP_START; /* Count and allocate PCI buses */ pci_node = fdt_node_offset_by_prop_value(fdt, pci_node, "device_type", "pci", 4); while (pci_node != -FDT_ERR_NOTFOUND) { pci_node = fdt_node_offset_by_prop_value(fdt, pci_node, "device_type", "pci", 4); pci_count++; } if (pci_count) { pci_hoses = malloc(sizeof(struct pci_controller) * pci_count); } else { printf("PCI: disabled\n\n"); return; } /* Spawn PCI buses based on device tree */ pci_node = fdt_node_offset_by_prop_value(fdt, pci_node, "device_type", "pci", 4); while (pci_node != -FDT_ERR_NOTFOUND) { struct fsl_pci_info pci_info = { }; const fdt32_t *reg; int r; reg = fdt_getprop(fdt, pci_node, "reg", NULL); pci_info.regs = fdt_translate_address(fdt, pci_node, reg); /* Map MMIO range */ r = pci_map_region(fdt, pci_node, 0, &pci_info.mem_phys, NULL, &pci_info.mem_size, &map_addr); if (r) break; /* Map PIO range */ r = pci_map_region(fdt, pci_node, 1, &pci_info.io_phys, NULL, &pci_info.io_size, &map_addr); if (r) break; /* * The PCI framework finds virtual addresses for the buses * through our address map, so tell it the physical addresses. */ pci_info.mem_bus = pci_info.mem_phys; pci_info.io_bus = pci_info.io_phys; /* Instantiate */ pci_info.pci_num = pci_num + 1; fsl_setup_hose(&pci_hoses[pci_num], pci_info.regs); printf("PCI: base address %lx\n", pci_info.regs); fsl_pci_init_port(&pci_info, &pci_hoses[pci_num], pci_num); /* Jump to next PCI node */ pci_node = fdt_node_offset_by_prop_value(fdt, pci_node, "device_type", "pci", 4); pci_num++; } puts("\n"); }
static int pic32_flash_probe(struct udevice *dev) { void *blob = (void *)gd->fdt_blob; int node = dev_of_offset(dev); const char *list, *end; const fdt32_t *cell; unsigned long addr, size; int parent, addrc, sizec; flash_info_t *info; int len, idx; /* * decode regs. there are multiple reg tuples, and they need to * match with reg-names. */ parent = fdt_parent_offset(blob, node); of_bus_default_count_cells(blob, parent, &addrc, &sizec); list = fdt_getprop(blob, node, "reg-names", &len); if (!list) return -ENOENT; end = list + len; cell = fdt_getprop(blob, node, "reg", &len); if (!cell) return -ENOENT; for (idx = 0, info = &flash_info[0]; list < end;) { addr = fdt_translate_address((void *)blob, node, cell + idx); size = fdt_addr_to_cpu(cell[idx + addrc]); len = strlen(list); if (!strncmp(list, "nvm", len)) { /* NVM controller */ nvm_regs_p = ioremap(addr, size); } else if (!strncmp(list, "bank", 4)) { /* Flash bank: use kseg0 cached address */ pic32_flash_bank_init(info, CKSEG0ADDR(addr), size); info++; } idx += addrc + sizec; list += len + 1; } /* disable flash write/erase operations */ writel(NVM_WREN, &nvm_regs_p->ctrl.clr); #if (CONFIG_SYS_MONITOR_BASE >= CONFIG_SYS_FLASH_BASE) /* monitor protection ON by default */ flash_protect(FLAG_PROTECT_SET, CONFIG_SYS_MONITOR_BASE, CONFIG_SYS_MONITOR_BASE + monitor_flash_len - 1, &flash_info[0]); #endif #ifdef CONFIG_ENV_IS_IN_FLASH /* ENV protection ON by default */ flash_protect(FLAG_PROTECT_SET, CONFIG_ENV_ADDR, CONFIG_ENV_ADDR + CONFIG_ENV_SECT_SIZE - 1, &flash_info[0]); #endif return 0; }