int syscon_reboot_probe(struct udevice *dev) { struct udevice *syscon; struct syscon_reboot_priv *priv = dev_get_priv(dev); int err; err = uclass_get_device_by_phandle(UCLASS_SYSCON, dev, "regmap", &syscon); if (err) { error("unable to find syscon device\n"); return err; } priv->regmap = syscon_get_regmap(syscon); if (!priv->regmap) { error("unable to find regmap\n"); return -ENODEV; } priv->offset = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev), "offset", 0); priv->mask = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev), "mask", 0); return 0; }
/** * dp83867_data_init - Convenience function for setting PHY specific data * * @phydev: the phy_device struct */ static int dp83867_of_init(struct phy_device *phydev) { struct dp83867_private *dp83867 = phydev->priv; struct udevice *dev = phydev->dev; int node = dev_of_offset(dev); const void *fdt = gd->fdt_blob; if (fdtdec_get_bool(fdt, node, "ti,max-output-impedance")) dp83867->io_impedance = DP83867_IO_MUX_CFG_IO_IMPEDANCE_MAX; else if (fdtdec_get_bool(fdt, node, "ti,min-output-impedance")) dp83867->io_impedance = DP83867_IO_MUX_CFG_IO_IMPEDANCE_MIN; else dp83867->io_impedance = -EINVAL; dp83867->rx_id_delay = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev), "ti,rx-internal-delay", -1); dp83867->tx_id_delay = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev), "ti,tx-internal-delay", -1); dp83867->fifo_depth = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev), "ti,fifo-depth", -1); return 0; }
int spi_slave_ofdata_to_platdata(const void *blob, int node, struct dm_spi_slave_platdata *plat) { int mode = 0, mode_rx = 0; int value; plat->cs = fdtdec_get_int(blob, node, "reg", -1); plat->max_hz = fdtdec_get_int(blob, node, "spi-max-frequency", 0); if (fdtdec_get_bool(blob, node, "spi-cpol")) mode |= SPI_CPOL; if (fdtdec_get_bool(blob, node, "spi-cpha")) mode |= SPI_CPHA; if (fdtdec_get_bool(blob, node, "spi-cs-high")) mode |= SPI_CS_HIGH; if (fdtdec_get_bool(blob, node, "spi-3wire")) mode |= SPI_3WIRE; if (fdtdec_get_bool(blob, node, "spi-half-duplex")) mode |= SPI_PREAMBLE; /* Device DUAL/QUAD mode */ value = fdtdec_get_uint(blob, node, "spi-tx-bus-width", 1); switch (value) { case 1: break; case 2: mode |= SPI_TX_DUAL; break; case 4: mode |= SPI_TX_QUAD; break; default: error("spi-tx-bus-width %d not supported\n", value); break; } plat->mode = mode; value = fdtdec_get_uint(blob, node, "spi-rx-bus-width", 1); switch (value) { case 1: break; case 2: mode_rx |= SPI_RX_DUAL; break; case 4: mode_rx |= SPI_RX_QUAD; break; default: error("spi-rx-bus-width %d not supported\n", value); break; } plat->mode_rx = mode_rx; return 0; }
static int simple_video_probe(struct udevice *dev) { struct video_uc_platdata *plat = dev_get_uclass_platdata(dev); struct video_priv *uc_priv = dev_get_uclass_priv(dev); const void *blob = gd->fdt_blob; const int node = dev_of_offset(dev); const char *format; fdt_addr_t base; fdt_size_t size; base = fdtdec_get_addr_size_auto_parent(blob, dev_of_offset(dev->parent), node, "reg", 0, &size, false); if (base == FDT_ADDR_T_NONE) { debug("%s: Failed to decode memory region\n", __func__); return -EINVAL; } debug("%s: base=%llx, size=%llu\n", __func__, base, size); /* * TODO is there some way to reserve the framebuffer * region so it isn't clobbered? */ plat->base = base; plat->size = size; video_set_flush_dcache(dev, true); debug("%s: Query resolution...\n", __func__); uc_priv->xsize = fdtdec_get_uint(blob, node, "width", 0); uc_priv->ysize = fdtdec_get_uint(blob, node, "height", 0); uc_priv->rot = 0; format = fdt_getprop(blob, node, "format", NULL); debug("%s: %dx%d@%s\n", __func__, uc_priv->xsize, uc_priv->ysize, format); if (strcmp(format, "r5g6b5") == 0) { uc_priv->bpix = VIDEO_BPP16; } else if (strcmp(format, "a8b8g8r8") == 0) { uc_priv->bpix = VIDEO_BPP32; } else { printf("%s: invalid format: %s\n", __func__, format); return -EINVAL; } return 0; }
static int socfpga_dwmmc_ofdata_to_platdata(struct udevice *dev) { /* FIXME: probe from DT eventually too/ */ const unsigned long clk = cm_get_mmc_controller_clk_hz(); struct dwmci_socfpga_priv_data *priv = dev_get_priv(dev); struct dwmci_host *host = &priv->host; int fifo_depth; if (clk == 0) { printf("DWMMC: MMC clock is zero!"); return -EINVAL; } fifo_depth = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "fifo-depth", 0); if (fifo_depth < 0) { printf("DWMMC: Can't get FIFO depth\n"); return -EINVAL; } host->name = dev->name; host->ioaddr = (void *)dev_get_addr(dev); host->buswidth = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "bus-width", 4); host->clksel = socfpga_dwmci_clksel; /* * TODO([email protected]): Remove the need for this hack. * We only have one dwmmc block on gen5 SoCFPGA. */ host->dev_index = 0; /* Fixed clock divide by 4 which due to the SDMMC wrapper */ host->bus_hz = clk; host->fifoth_val = MSIZE(0x2) | RX_WMARK(fifo_depth / 2 - 1) | TX_WMARK(fifo_depth / 2); priv->drvsel = fdtdec_get_uint(gd->fdt_blob, dev->of_offset, "drvsel", 3); priv->smplsel = fdtdec_get_uint(gd->fdt_blob, dev->of_offset, "smplsel", 0); host->priv = priv; return 0; }
static int get_bridge_init_val(const void *blob, int compat_id) { int node; node = fdtdec_next_compatible(blob, 0, compat_id); if (node < 0) return 0; return fdtdec_get_uint(blob, node, "init-val", 0); }
static int cros_ec_i2c_ofdata_to_platdata(struct udevice *dev) { struct cros_ec_i2c_bus *i2c_bus = dev_get_priv(dev); const void *blob = gd->fdt_blob; int node = dev_of_offset(dev); i2c_bus->remote_bus = fdtdec_get_uint(blob, node, "google,remote-bus", 0); return 0; }
static int omap3_spi_probe(struct udevice *dev) { struct omap3_spi_priv *priv = dev_get_priv(dev); const void *blob = gd->fdt_blob; int node = dev->of_offset; priv->regs = (struct mcspi *)dev_get_addr(dev); priv->pin_dir = fdtdec_get_uint(blob, node, "ti,pindir-d0-out-d1-in", MCSPI_PINDIR_D0_IN_D1_OUT); priv->wordlen = SPI_DEFAULT_WORDLEN; return 0; }
static int dwc_ahci_ofdata_to_platdata(struct udevice *dev) { struct dwc_ahci_priv *priv = dev_get_priv(dev); struct scsi_platdata *plat = dev_get_uclass_platdata(dev); fdt_addr_t addr; plat->max_id = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev), "max-id", CONFIG_SYS_SCSI_MAX_SCSI_ID); plat->max_lun = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev), "max-lun", CONFIG_SYS_SCSI_MAX_LUN); priv->base = map_physmem(devfdt_get_addr(dev), sizeof(void *), MAP_NOCACHE); addr = devfdt_get_addr_index(dev, 1); if (addr != FDT_ADDR_T_NONE) { priv->wrapper_base = map_physmem(addr, sizeof(void *), MAP_NOCACHE); } else { priv->wrapper_base = NULL; } return 0; }
static int cadence_spi_ofdata_to_platdata(struct udevice *bus) { struct cadence_spi_platdata *plat = bus->platdata; const void *blob = gd->fdt_blob; int node = bus->of_offset; int subnode; u32 data[4]; int ret; /* 2 base addresses are needed, lets get them from the DT */ ret = fdtdec_get_int_array(blob, node, "reg", data, ARRAY_SIZE(data)); if (ret) { printf("Error: Can't get base addresses (ret=%d)!\n", ret); return -ENODEV; } plat->regbase = (void *)data[0]; plat->ahbbase = (void *)data[2]; plat->sram_size = fdtdec_get_int(blob, node, "sram-size", 128); /* All other paramters are embedded in the child node */ subnode = fdt_first_subnode(blob, node); if (subnode < 0) { printf("Error: subnode with SPI flash config missing!\n"); return -ENODEV; } /* Use 500 KHz as a suitable default */ plat->max_hz = fdtdec_get_uint(blob, subnode, "spi-max-frequency", 500000); /* Read other parameters from DT */ plat->page_size = fdtdec_get_int(blob, subnode, "page-size", 256); plat->block_size = fdtdec_get_int(blob, subnode, "block-size", 16); plat->tshsl_ns = fdtdec_get_int(blob, subnode, "tshsl-ns", 200); plat->tsd2d_ns = fdtdec_get_int(blob, subnode, "tsd2d-ns", 255); plat->tchsh_ns = fdtdec_get_int(blob, subnode, "tchsh-ns", 20); plat->tslch_ns = fdtdec_get_int(blob, subnode, "tslch-ns", 20); debug("%s: regbase=%p ahbbase=%p max-frequency=%d page-size=%d\n", __func__, plat->regbase, plat->ahbbase, plat->max_hz, plat->page_size); return 0; }
int at91_clk_of_xlate(struct clk *clk, struct fdtdec_phandle_args *args) { int periph; if (args->args_count) { debug("Invalid args_count: %d\n", args->args_count); return -EINVAL; } periph = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(clk->dev), "reg", -1); if (periph < 0) return -EINVAL; clk->id = periph; return 0; }
static int uniphier_gpio_probe(struct udevice *dev) { struct uniphier_gpio_priv *priv = dev_get_priv(dev); struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); fdt_addr_t addr; addr = devfdt_get_addr(dev); if (addr == FDT_ADDR_T_NONE) return -EINVAL; priv->regs = devm_ioremap(dev, addr, SZ_512); if (!priv->regs) return -ENOMEM; uc_priv->gpio_count = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev), "ngpios", 0); return 0; }
static int fixed_regulator_ofdata_to_platdata(struct udevice *dev) { struct dm_regulator_uclass_platdata *uc_pdata; struct fixed_regulator_platdata *dev_pdata; struct gpio_desc *gpio; const void *blob = gd->fdt_blob; int node = dev->of_offset, flags = GPIOD_IS_OUT; int ret; dev_pdata = dev_get_platdata(dev); uc_pdata = dev_get_uclass_platdata(dev); if (!uc_pdata) return -ENXIO; /* Set type to fixed */ uc_pdata->type = REGULATOR_TYPE_FIXED; if (fdtdec_get_bool(blob, node, "enable-active-high")) flags |= GPIOD_IS_OUT_ACTIVE; /* Get fixed regulator optional enable GPIO desc */ gpio = &dev_pdata->gpio; ret = gpio_request_by_name(dev, "gpio", 0, gpio, flags); if (ret) { debug("Fixed regulator optional enable GPIO - not found! Error: %d\n", ret); if (ret != -ENOENT) return ret; } /* Get optional ramp up delay */ dev_pdata->startup_delay_us = fdtdec_get_uint(gd->fdt_blob, dev->of_offset, "startup-delay-us", 0); return 0; }
static int zynq_gem_ofdata_to_platdata(struct udevice *dev) { struct eth_pdata *pdata = dev_get_platdata(dev); struct zynq_gem_priv *priv = dev_get_priv(dev); int node = dev_of_offset(dev); const char *phy_mode; pdata->iobase = (phys_addr_t)devfdt_get_addr(dev); priv->iobase = (struct zynq_gem_regs *)pdata->iobase; /* Hardcode for now */ priv->phyaddr = -1; priv->phy_of_handle = fdtdec_lookup_phandle(gd->fdt_blob, node, "phy-handle"); if (priv->phy_of_handle > 0) priv->phyaddr = fdtdec_get_int(gd->fdt_blob, priv->phy_of_handle, "reg", -1); phy_mode = fdt_getprop(gd->fdt_blob, node, "phy-mode", NULL); if (phy_mode) pdata->phy_interface = phy_get_interface_by_name(phy_mode); if (pdata->phy_interface == -1) { debug("%s: Invalid PHY interface '%s'\n", __func__, phy_mode); return -EINVAL; } priv->interface = pdata->phy_interface; priv->max_speed = fdtdec_get_uint(gd->fdt_blob, priv->phy_of_handle, "max-speed", SPEED_1000); priv->int_pcs = fdtdec_get_bool(gd->fdt_blob, node, "is-internal-pcspma"); printf("ZYNQ GEM: %lx, phyaddr %x, interface %s\n", (ulong)priv->iobase, priv->phyaddr, phy_string_for_interface(priv->interface)); return 0; }
static int socfpga_dwmci_of_probe(const void *blob, int node, const int idx) { /* FIXME: probe from DT eventually too/ */ const unsigned long clk = cm_get_mmc_controller_clk_hz(); struct dwmci_host *host; struct dwmci_socfpga_priv_data *priv; fdt_addr_t reg_base; int bus_width, fifo_depth; if (clk == 0) { printf("DWMMC%d: MMC clock is zero!", idx); return -EINVAL; } /* Get the register address from the device node */ reg_base = fdtdec_get_addr(blob, node, "reg"); if (!reg_base) { printf("DWMMC%d: Can't get base address\n", idx); return -EINVAL; } /* Get the bus width from the device node */ bus_width = fdtdec_get_int(blob, node, "bus-width", 0); if (bus_width <= 0) { printf("DWMMC%d: Can't get bus-width\n", idx); return -EINVAL; } fifo_depth = fdtdec_get_int(blob, node, "fifo-depth", 0); if (fifo_depth < 0) { printf("DWMMC%d: Can't get FIFO depth\n", idx); return -EINVAL; } /* Allocate the host */ host = calloc(1, sizeof(*host)); if (!host) return -ENOMEM; /* Allocate the priv */ priv = calloc(1, sizeof(*priv)); if (!priv) { free(host); return -ENOMEM; } host->name = "SOCFPGA DWMMC"; host->ioaddr = (void *)reg_base; host->buswidth = bus_width; host->clksel = socfpga_dwmci_clksel; host->dev_index = idx; /* Fixed clock divide by 4 which due to the SDMMC wrapper */ host->bus_hz = clk; host->fifoth_val = MSIZE(0x2) | RX_WMARK(fifo_depth / 2 - 1) | TX_WMARK(fifo_depth / 2); priv->drvsel = fdtdec_get_uint(blob, node, "drvsel", 3); priv->smplsel = fdtdec_get_uint(blob, node, "smplsel", 0); host->priv = priv; return add_dwmci(host, host->bus_hz, 400000); }
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; }