static int owl_mac_parse_fdtdec(struct owl_mac_info *info) { int node,ret; //const char *mac_compat = OWL_MAC_COMPAT; node = fdt_node_offset_by_compatible(gd->fdt_blob,0,OWL_MAC_COMPAT); if(node <= 0){ debug("Can't get owl-ethernet node\n"); return -1; } ret = fdtdec_get_is_enabled(gd->fdt_blob,node); if(!ret){ debug("Disable by dts\n"); return -1; } info->phy_addr = fdtdec_get_int(gd->fdt_blob, node, "phy_addr", -1); printf("owl_mac_parse_fdtdec,phy_addr %d\n",info->phy_addr); owl_fdtdec_decode_gpio(gd->fdt_blob, node, "phy-power-gpios",&info->phy_power_gpio); owl_fdtdec_decode_gpio(gd->fdt_blob, node, "phy-reset-gpios",&info->phy_reset_gpio); printf("owl_mac_parse_fdtdec,power-gpio %d\n",info->phy_power_gpio.gpio,info->phy_power_gpio.flags); printf("owl_mac_parse_fdtdec,reset-gpio %d\n",info->phy_reset_gpio.gpio,info->phy_reset_gpio.flags); return 0; }
int dm_scan_fdt_node(struct udevice *parent, const void *blob, int offset, bool pre_reloc_only) { int ret = 0, err; for (offset = fdt_first_subnode(blob, offset); offset > 0; offset = fdt_next_subnode(blob, offset)) { if (pre_reloc_only && !fdt_getprop(blob, offset, "u-boot,dm-pre-reloc", NULL)) continue; if (!fdtdec_get_is_enabled(blob, offset)) { dm_dbg(" - ignoring disabled device\n"); continue; } err = lists_bind_fdt(parent, blob, offset, NULL); if (err && !ret) { ret = err; debug("%s: ret=%d\n", fdt_get_name(blob, offset, NULL), ret); } } if (ret) dm_warn("Some drivers failed to bind\n"); return ret; }
int tegra_xusb_process_nodes(const void *fdt, int nodes[], unsigned int count, const struct tegra_xusb_padctl_soc *socdata) { unsigned int i; int err; for (i = 0; i < count; i++) { if (!fdtdec_get_is_enabled(fdt, nodes[i])) continue; padctl.socdata = socdata; err = tegra_xusb_padctl_parse_dt(&padctl, fdt, nodes[i]); if (err < 0) { error("failed to parse DT: %d", err); continue; } /* deassert XUSB padctl reset */ reset_set_enable(PERIPH_ID_XUSB_PADCTL, 0); err = tegra_xusb_padctl_config_apply(&padctl, &padctl.config); if (err < 0) { error("failed to apply pinmux: %d", err); continue; } /* only a single instance is supported */ break; } return 0; }
static int get_next_memory_node(const void *blob, int mem) { do { mem = fdt_node_offset_by_prop_value(gd->fdt_blob, mem, "device_type", "memory", 7); } while (!fdtdec_get_is_enabled(blob, mem)); return mem; }
int dev_read_enabled(struct udevice *dev) { ofnode node = dev_ofnode(dev); if (ofnode_is_np(node)) return of_device_is_available(ofnode_to_np(node)); else return fdtdec_get_is_enabled(gd->fdt_blob, ofnode_to_offset(node)); }
static int device_okay(const char *path) { int node; node = fdt_path_offset(gd->fdt_blob, path); if (node < 0) return 0; return fdtdec_get_is_enabled(gd->fdt_blob, node); }
static int process_nodes(const void *fdt, int nodes[], unsigned int count) { unsigned int i; for (i = 0; i < count; i++) { enum fdt_compat_id id; int err; if (!fdtdec_get_is_enabled(fdt, nodes[i])) continue; id = fdtdec_lookup(fdt, nodes[i]); switch (id) { case COMPAT_NVIDIA_TEGRA124_XUSB_PADCTL: break; default: error("tegra-xusb-padctl: unsupported compatible: %s", fdtdec_get_compatible(id)); continue; } padctl->num_lanes = ARRAY_SIZE(tegra124_lanes); padctl->lanes = tegra124_lanes; padctl->num_functions = ARRAY_SIZE(tegra124_functions); padctl->functions = tegra124_functions; err = tegra_xusb_padctl_parse_dt(padctl, fdt, nodes[i]); if (err < 0) { error("tegra-xusb-padctl: failed to parse DT: %d", err); continue; } /* deassert XUSB padctl reset */ reset_set_enable(PERIPH_ID_XUSB_PADCTL, 0); err = tegra_xusb_padctl_config_apply(padctl, &padctl->config); if (err < 0) { error("tegra-xusb-padctl: failed to apply pinmux: %d", err); continue; } /* only a single instance is supported */ break; } return 0; }
static int fdt_decode_usb(const void *blob, int node, struct fdt_usb *config) { const char *phy, *mode; config->reg = (struct usb_ctlr *)fdtdec_get_addr(blob, node, "reg"); mode = fdt_getprop(blob, node, "dr_mode", NULL); if (mode) { if (0 == strcmp(mode, "host")) config->dr_mode = DR_MODE_HOST; else if (0 == strcmp(mode, "peripheral")) config->dr_mode = DR_MODE_DEVICE; else if (0 == strcmp(mode, "otg")) config->dr_mode = DR_MODE_OTG; else { debug("%s: Cannot decode dr_mode '%s'\n", __func__, mode); return -FDT_ERR_NOTFOUND; } } else { config->dr_mode = DR_MODE_HOST; } phy = fdt_getprop(blob, node, "phy_type", NULL); config->utmi = phy && 0 == strcmp("utmi", phy); config->ulpi = phy && 0 == strcmp("ulpi", phy); config->enabled = fdtdec_get_is_enabled(blob, node); config->has_legacy_mode = fdtdec_get_bool(blob, node, "nvidia,has-legacy-mode"); if (config->has_legacy_mode) port_addr_clear_csc = (u32) config->reg; config->periph_id = clock_decode_periph_id(blob, node); if (config->periph_id == PERIPH_ID_NONE) { debug("%s: Missing/invalid peripheral ID\n", __func__); return -FDT_ERR_NOTFOUND; } fdtdec_decode_gpio(blob, node, "nvidia,vbus-gpio", &config->vbus_gpio); fdtdec_decode_gpio(blob, node, "nvidia,phy-reset-gpio", &config->phy_reset_gpio); debug("enabled=%d, legacy_mode=%d, utmi=%d, ulpi=%d, periph_id=%d, " "vbus=%d, phy_reset=%d, dr_mode=%d\n", config->enabled, config->has_legacy_mode, config->utmi, config->ulpi, config->periph_id, config->vbus_gpio.gpio, config->phy_reset_gpio.gpio, config->dr_mode); return 0; }
/** * Get the host address and peripheral ID for a node. * * @param blob fdt blob * @param node Device index (0-3) * @param host Structure to fill in (reg, width, mmc_id) */ static int mmc_get_config(const void *blob, int node, struct mmc_host *host, bool *removablep) { debug("%s: node = %d\n", __func__, node); host->enabled = fdtdec_get_is_enabled(blob, node); host->reg = (struct tegra_mmc *)fdtdec_get_addr(blob, node, "reg"); if ((fdt_addr_t)host->reg == FDT_ADDR_T_NONE) { debug("%s: no sdmmc base reg info found\n", __func__); return -FDT_ERR_NOTFOUND; } host->mmc_id = clock_decode_periph_id(blob, node); if (host->mmc_id == PERIPH_ID_NONE) { debug("%s: could not decode periph id\n", __func__); return -FDT_ERR_NOTFOUND; } /* * NOTE: mmc->bus_width is determined by mmc.c dynamically. * TBD: Override it with this value? */ host->width = fdtdec_get_int(blob, node, "bus-width", 0); if (!host->width) debug("%s: no sdmmc width found\n", __func__); /* These GPIOs are optional */ gpio_request_by_name_nodev(blob, node, "cd-gpios", 0, &host->cd_gpio, GPIOD_IS_IN); gpio_request_by_name_nodev(blob, node, "wp-gpios", 0, &host->wp_gpio, GPIOD_IS_IN); gpio_request_by_name_nodev(blob, node, "power-gpios", 0, &host->pwr_gpio, GPIOD_IS_OUT); *removablep = !fdtdec_get_bool(blob, node, "non-removable"); debug("%s: found controller at %p, width = %d, periph_id = %d\n", __func__, host->reg, host->width, host->mmc_id); return 0; }
/* TODO: Can we tighten this code up a little? */ int fdtdec_add_aliases_for_id(const void *blob, const char *name, enum fdt_compat_id id, int *node_list, int maxcount) { int name_len = strlen(name); int nodes[maxcount]; int num_found = 0; int offset, node; int alias_node; int count; int i, j; /* find the alias node if present */ alias_node = fdt_path_offset(blob, "/aliases"); /* * start with nothing, and we can assume that the root node can't * match */ memset(nodes, '\0', sizeof(nodes)); /* First find all the compatible nodes */ for (node = count = 0; node >= 0 && count < maxcount;) { node = fdtdec_next_compatible(blob, node, id); if (node >= 0) nodes[count++] = node; } if (node >= 0) debug("%s: warning: maxcount exceeded with alias '%s'\n", __func__, name); /* Now find all the aliases */ for (offset = fdt_first_property_offset(blob, alias_node); offset > 0; offset = fdt_next_property_offset(blob, offset)) { const struct fdt_property *prop; const char *path; int number; int found; node = 0; prop = fdt_get_property_by_offset(blob, offset, NULL); path = fdt_string(blob, fdt32_to_cpu(prop->nameoff)); if (prop->len && 0 == strncmp(path, name, name_len)) node = fdt_path_offset(blob, prop->data); if (node <= 0) continue; /* Get the alias number */ number = simple_strtoul(path + name_len, NULL, 10); if (number < 0 || number >= maxcount) { debug("%s: warning: alias '%s' is out of range\n", __func__, path); continue; } /* Make sure the node we found is actually in our list! */ found = -1; for (j = 0; j < count; j++) if (nodes[j] == node) { found = j; break; } if (found == -1) { debug("%s: warning: alias '%s' points to a node " "'%s' that is missing or is not compatible " " with '%s'\n", __func__, path, fdt_get_name(blob, node, NULL), compat_names[id]); continue; } /* * Add this node to our list in the right place, and mark * it as done. */ if (fdtdec_get_is_enabled(blob, node)) { if (node_list[number]) { debug("%s: warning: alias '%s' requires that " "a node be placed in the list in a " "position which is already filled by " "node '%s'\n", __func__, path, fdt_get_name(blob, node, NULL)); continue; } node_list[number] = node; if (number >= num_found) num_found = number + 1; } nodes[found] = 0; } /* Add any nodes not mentioned by an alias */ for (i = j = 0; i < maxcount; i++) { if (!node_list[i]) { for (; j < maxcount; j++) if (nodes[j] && fdtdec_get_is_enabled(blob, nodes[j])) break; /* Have we run out of nodes to add? */ if (j == maxcount) break; assert(!node_list[i]); node_list[i] = nodes[j++]; if (i >= num_found) num_found = i + 1; } } return num_found; }
int board_usb_init(int index, enum usb_init_type init) { struct fdtdec_phandle_args args; struct udevice *dev; const void *blob = gd->fdt_blob; struct clk clk; struct phy phy; int node; int phy_provider; int ret; /* find the usb otg node */ node = fdt_node_offset_by_compatible(blob, -1, "snps,dwc2"); if (node < 0) { debug("Not found usb_otg device\n"); return -ENODEV; } if (!fdtdec_get_is_enabled(blob, node)) { debug("stm32 usbotg is disabled in the device tree\n"); return -ENODEV; } /* Enable clock */ ret = fdtdec_parse_phandle_with_args(blob, node, "clocks", "#clock-cells", 0, 0, &args); if (ret) { debug("usbotg has no clocks defined in the device tree\n"); return ret; } ret = uclass_get_device_by_of_offset(UCLASS_CLK, args.node, &dev); if (ret) return ret; if (args.args_count != 1) { debug("Can't find clock ID in the device tree\n"); return -ENODATA; } clk.dev = dev; clk.id = args.args[0]; ret = clk_enable(&clk); if (ret) { debug("Failed to enable usbotg clock\n"); return ret; } /* Reset */ ret = fdtdec_parse_phandle_with_args(blob, node, "resets", "#reset-cells", 0, 0, &args); if (ret) { debug("usbotg has no resets defined in the device tree\n"); goto clk_err; } ret = uclass_get_device_by_of_offset(UCLASS_RESET, args.node, &dev); if (ret || args.args_count != 1) goto clk_err; usbotg_reset.dev = dev; usbotg_reset.id = args.args[0]; reset_assert(&usbotg_reset); udelay(2); reset_deassert(&usbotg_reset); /* Get USB PHY */ ret = fdtdec_parse_phandle_with_args(blob, node, "phys", "#phy-cells", 0, 0, &args); if (!ret) { phy_provider = fdt_parent_offset(blob, args.node); ret = uclass_get_device_by_of_offset(UCLASS_PHY, phy_provider, &dev); if (ret) goto clk_err; phy.dev = dev; phy.id = fdtdec_get_uint(blob, args.node, "reg", -1); ret = generic_phy_power_on(&phy); if (ret) { debug("unable to power on the phy\n"); goto clk_err; } ret = generic_phy_init(&phy); if (ret) { debug("failed to init usb phy\n"); goto phy_power_err; } } /* Parse and store data needed for gadget */ stm32mp_otg_data.regs_otg = fdtdec_get_addr(blob, node, "reg"); if (stm32mp_otg_data.regs_otg == FDT_ADDR_T_NONE) { debug("usbotg: can't get base address\n"); ret = -ENODATA; goto phy_init_err; } stm32mp_otg_data.rx_fifo_sz = fdtdec_get_int(blob, node, "g-rx-fifo-size", 0); stm32mp_otg_data.np_tx_fifo_sz = fdtdec_get_int(blob, node, "g-np-tx-fifo-size", 0); stm32mp_otg_data.tx_fifo_sz = fdtdec_get_int(blob, node, "g-tx-fifo-size", 0); /* Enable voltage level detector */ if (!(fdtdec_parse_phandle_with_args(blob, node, "usb33d-supply", NULL, 0, 0, &args))) { if (!uclass_get_device_by_of_offset(UCLASS_REGULATOR, args.node, &dev)) { ret = regulator_set_enable(dev, true); if (ret) { debug("Failed to enable usb33d\n"); goto phy_init_err; } } } /* Enable vbus sensing */ setbits_le32(stm32mp_otg_data.regs_otg + STM32MP_GGPIO, STM32MP_GGPIO_VBUS_SENSING); return dwc2_udc_probe(&stm32mp_otg_data); phy_init_err: generic_phy_exit(&phy); phy_power_err: generic_phy_power_off(&phy); clk_err: clk_disable(&clk); return ret; }
int cros_ec_init(const void *blob, struct cros_ec_dev **cros_ecp) { char id[MSG_BYTES]; struct cros_ec_dev *dev; int node = 0; *cros_ecp = NULL; do { node = fdtdec_next_compatible(blob, node, COMPAT_GOOGLE_CROS_EC); if (node < 0) { debug("%s: Node not found\n", __func__); return 0; } } while (!fdtdec_get_is_enabled(blob, node)); if (cros_ec_decode_fdt(blob, node, &dev)) { debug("%s: Failed to decode device.\n", __func__); return -CROS_EC_ERR_FDT_DECODE; } switch (dev->interface) { #ifdef CONFIG_CROS_EC_SPI case CROS_EC_IF_SPI: if (cros_ec_spi_init(dev, blob)) { debug("%s: Could not setup SPI interface\n", __func__); return -CROS_EC_ERR_DEV_INIT; } break; #endif #ifdef CONFIG_CROS_EC_I2C case CROS_EC_IF_I2C: if (cros_ec_i2c_init(dev, blob)) return -CROS_EC_ERR_DEV_INIT; break; #endif #ifdef CONFIG_CROS_EC_LPC case CROS_EC_IF_LPC: if (cros_ec_lpc_init(dev, blob)) return -CROS_EC_ERR_DEV_INIT; break; #endif #ifdef CONFIG_CROS_EC_SANDBOX case CROS_EC_IF_SANDBOX: if (cros_ec_sandbox_init(dev, blob)) return -CROS_EC_ERR_DEV_INIT; break; #endif case CROS_EC_IF_NONE: default: return 0; } /* we will poll the EC interrupt line */ fdtdec_setup_gpio(&dev->ec_int); if (fdt_gpio_isvalid(&dev->ec_int)) gpio_direction_input(dev->ec_int.gpio); if (cros_ec_check_version(dev)) { debug("%s: Could not detect CROS-EC version\n", __func__); return -CROS_EC_ERR_CHECK_VERSION; } if (cros_ec_read_id(dev, id, sizeof(id))) { debug("%s: Could not read KBC ID\n", __func__); return -CROS_EC_ERR_READ_ID; } /* Remember this device for use by the cros_ec command */ last_dev = *cros_ecp = dev; debug("Google Chrome EC CROS-EC driver ready, id '%s'\n", id); return 0; }
/** * Get the host address and peripheral ID for a node. * * @param blob fdt blob * @param node Device index (0-3) * @param host Structure to fill in (reg, width, mmc_id) */ static int mmc_get_config(const void *blob, int node, struct mmc_host *host, bool *removablep) { debug("%s: node = %d\n", __func__, node); host->enabled = fdtdec_get_is_enabled(blob, node); host->reg = (struct tegra_mmc *)fdtdec_get_addr(blob, node, "reg"); if ((fdt_addr_t)host->reg == FDT_ADDR_T_NONE) { debug("%s: no sdmmc base reg info found\n", __func__); return -FDT_ERR_NOTFOUND; } #ifdef CONFIG_TEGRA186 { /* * FIXME: This variable should go away when the MMC device * actually is a udevice. */ struct udevice dev; int ret; dev.of_offset = node; ret = reset_get_by_name(&dev, "sdhci", &host->reset_ctl); if (ret) { debug("reset_get_by_name() failed: %d\n", ret); return ret; } ret = clk_get_by_index(&dev, 0, &host->clk); if (ret) { debug("clk_get_by_index() failed: %d\n", ret); return ret; } } #else host->mmc_id = clock_decode_periph_id(blob, node); if (host->mmc_id == PERIPH_ID_NONE) { debug("%s: could not decode periph id\n", __func__); return -FDT_ERR_NOTFOUND; } #endif /* * NOTE: mmc->bus_width is determined by mmc.c dynamically. * TBD: Override it with this value? */ host->width = fdtdec_get_int(blob, node, "bus-width", 0); if (!host->width) debug("%s: no sdmmc width found\n", __func__); /* These GPIOs are optional */ gpio_request_by_name_nodev(blob, node, "cd-gpios", 0, &host->cd_gpio, GPIOD_IS_IN); gpio_request_by_name_nodev(blob, node, "wp-gpios", 0, &host->wp_gpio, GPIOD_IS_IN); gpio_request_by_name_nodev(blob, node, "power-gpios", 0, &host->pwr_gpio, GPIOD_IS_OUT); *removablep = !fdtdec_get_bool(blob, node, "non-removable"); debug("%s: found controller at %p, width = %d, periph_id = %d\n", __func__, host->reg, host->width, #ifndef CONFIG_TEGRA186 host->mmc_id #else -1 #endif ); return 0; }