Beispiel #1
0
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;
}
Beispiel #2
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;
}
Beispiel #3
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;
}
Beispiel #4
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);
}
Beispiel #7
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;
}
Beispiel #9
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;
}
Beispiel #10
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;
}
Beispiel #11
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;
}
Beispiel #12
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;
}
Beispiel #13
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;
}
Beispiel #14
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;
}
Beispiel #15
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);
}
Beispiel #16
0
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;
}