コード例 #1
0
ファイル: test-fdt.c プロジェクト: SunnyBrother/u-boot-at91
/* Test that we can find a device by device tree offset */
static int dm_test_fdt_offset(struct unit_test_state *uts)
{
	const void *blob = gd->fdt_blob;
	struct udevice *dev;
	int node;

	node = fdt_path_offset(blob, "/e-test");
	ut_assert(node > 0);
	ut_assertok(uclass_get_device_by_of_offset(UCLASS_TEST_FDT, node,
						   &dev));
	ut_asserteq_str("e-test", dev->name);

	/* This node should not be bound */
	node = fdt_path_offset(blob, "/junk");
	ut_assert(node > 0);
	ut_asserteq(-ENODEV, uclass_get_device_by_of_offset(UCLASS_TEST_FDT,
							    node, &dev));

	/* This is not a top level node so should not be probed */
	node = fdt_path_offset(blob, "/some-bus/c-test@5");
	ut_assert(node > 0);
	ut_asserteq(-ENODEV, uclass_get_device_by_of_offset(UCLASS_TEST_FDT,
							    node, &dev));

	return 0;
}
コード例 #2
0
static void serial_find_console_or_panic(void)
{
#ifdef CONFIG_OF_CONTROL
	int node;

	/* Check for a chosen console */
	node = fdtdec_get_chosen_node(gd->fdt_blob, "stdout-path");
	if (node < 0)
		node = fdtdec_get_alias_node(gd->fdt_blob, "console");
	if (!uclass_get_device_by_of_offset(UCLASS_SERIAL, node, &cur_dev))
		return;

	/*
	 * If the console is not marked to be bound before relocation, bind
	 * it anyway.
	 */
	if (node > 0 &&
	    !lists_bind_fdt(gd->dm_root, gd->fdt_blob, node, &cur_dev)) {
		if (!device_probe(cur_dev))
			return;
		cur_dev = NULL;
	}
#endif
	/*
	 * Failing that, get the device with sequence number 0, or in extremis
	 * just the first serial device we can find. But we insist on having
	 * a console (even if it is silent).
	 */
	if (uclass_get_device_by_seq(UCLASS_SERIAL, 0, &cur_dev) &&
	    (uclass_first_device(UCLASS_SERIAL, &cur_dev) || !cur_dev))
		panic("No serial driver found");
}
コード例 #3
0
static int pwm_regulator_ofdata_to_platdata(struct udevice *dev)
{
	struct pwm_regulator_info *priv = dev_get_priv(dev);
	struct fdtdec_phandle_args args;
	const void *blob = gd->fdt_blob;
	int node = dev_of_offset(dev);
	int ret;

	ret = fdtdec_parse_phandle_with_args(blob, node, "pwms", "#pwm-cells",
					     0, 0, &args);
	if (ret) {
		debug("%s: Cannot get PWM phandle: ret=%d\n", __func__, ret);
		return ret;
	}

	priv->period_ns = args.args[1];
	priv->polarity = args.args[2];

	priv->init_voltage = fdtdec_get_int(blob, node,
			"regulator-init-microvolt", -1);
	if (priv->init_voltage < 0) {
		printf("Cannot find regulator pwm init_voltage\n");
		return -EINVAL;
	}

	ret = uclass_get_device_by_of_offset(UCLASS_PWM, args.node, &priv->pwm);
	if (ret) {
		debug("%s: Cannot get PWM: ret=%d\n", __func__, ret);
		return ret;
	}

	return 0;
}
コード例 #4
0
ファイル: sdram.c プロジェクト: shreejithshanker/u-boot-xlnx
static int get_mrc_entry(struct udevice **devp, struct fmap_entry *entry)
{
    const void *blob = gd->fdt_blob;
    int node, spi_node, mrc_node;
    int upto;
    int ret;

    /* Find the flash chip within the SPI controller node */
    upto = 0;
    spi_node = fdtdec_next_alias(blob, "spi", COMPAT_INTEL_ICH_SPI, &upto);
    if (spi_node < 0)
        return -ENOENT;
    node = fdt_first_subnode(blob, spi_node);
    if (node < 0)
        return -ECHILD;

    /* Find the place where we put the MRC cache */
    mrc_node = fdt_subnode_offset(blob, node, "rw-mrc-cache");
    if (mrc_node < 0)
        return -EPERM;

    if (fdtdec_read_fmap_entry(blob, mrc_node, "rm-mrc-cache", entry))
        return -EINVAL;

    if (devp) {
        debug("getting sf\n");
        ret = uclass_get_device_by_of_offset(UCLASS_SPI_FLASH, node,
                                             devp);
        debug("ret = %d\n", ret);
        if (ret)
            return ret;
    }

    return 0;
}
コード例 #5
0
int i2c_get_bus_num_fdt(int node)
{
	struct udevice *bus;
	int ret;

	ret = uclass_get_device_by_of_offset(UCLASS_I2C, node, &bus);
	if (ret)
		return ret;

	return bus->seq;
}
コード例 #6
0
static int pwm_backlight_ofdata_to_platdata(struct udevice *dev)
{
	struct pwm_backlight_priv *priv = dev_get_priv(dev);
	struct fdtdec_phandle_args args;
	const void *blob = gd->fdt_blob;
	int node = dev->of_offset;
	int index, ret, count, len;
	const u32 *cell;

	ret = uclass_get_device_by_phandle(UCLASS_REGULATOR, dev,
					   "power-supply", &priv->reg);
	if (ret) {
		debug("%s: Cannot get power supply: ret=%d\n", __func__, ret);
		return ret;
	}
	ret = gpio_request_by_name(dev, "enable-gpios", 0, &priv->enable,
				   GPIOD_IS_OUT);
	if (ret) {
		debug("%s: Warning: cannot get enable GPIO: ret=%d\n",
		      __func__, ret);
		if (ret != -ENOENT)
			return ret;
	}
	ret = fdtdec_parse_phandle_with_args(blob, node, "pwms", "#pwm-cells",
					     0, 0, &args);
	if (ret) {
		debug("%s: Cannot get PWM phandle: ret=%d\n", __func__, ret);
		return ret;
	}

	ret = uclass_get_device_by_of_offset(UCLASS_PWM, args.node, &priv->pwm);
	if (ret) {
		debug("%s: Cannot get PWM: ret=%d\n", __func__, ret);
		return ret;
	}
	priv->channel = args.args[0];
	priv->period_ns = args.args[1];

	index = fdtdec_get_int(blob, node, "default-brightness-level", 255);
	cell = fdt_getprop(blob, node, "brightness-levels", &len);
	count = len / sizeof(u32);
	if (cell && count > index) {
		priv->default_level = fdt32_to_cpu(cell[index]);
		priv->max_level = fdt32_to_cpu(cell[count - 1]);
	} else {
		priv->default_level = index;
		priv->max_level = 255;
	}


	return 0;
}
コード例 #7
0
ファイル: spi-uclass.c プロジェクト: goldelico/gta04-uboot
/* Compatibility function - to be removed */
struct spi_slave *spi_setup_slave_fdt(const void *blob, int node,
				      int bus_node)
{
	struct udevice *bus, *dev;
	int ret;

	ret = uclass_get_device_by_of_offset(UCLASS_SPI, bus_node, &bus);
	if (ret)
		return NULL;
	ret = device_get_child_by_of_offset(bus, node, &dev);
	if (ret)
		return NULL;
	return dev_get_parent_priv(dev);
}
コード例 #8
0
/**
 * pinctrl_select_state_full() - full implementation of pinctrl_select_state
 *
 * @dev: peripheral device
 * @statename: state name, like "default"
 * @return: 0 on success, or negative error code on failure
 */
static int pinctrl_select_state_full(struct udevice *dev, const char *statename)
{
	const void *fdt = gd->fdt_blob;
	int node = dev->of_offset;
	char propname[32]; /* long enough */
	const fdt32_t *list;
	uint32_t phandle;
	int config_node;
	struct udevice *config;
	int state, size, i, ret;

	state = fdt_find_string(fdt, node, "pinctrl-names", statename);
	if (state < 0) {
		char *end;
		/*
		 * If statename is not found in "pinctrl-names",
		 * assume statename is just the integer state ID.
		 */
		state = simple_strtoul(statename, &end, 10);
		if (*end)
			return -EINVAL;
	}

	snprintf(propname, sizeof(propname), "pinctrl-%d", state);
	list = fdt_getprop(fdt, node, propname, &size);
	if (!list)
		return -EINVAL;

	size /= sizeof(*list);
	for (i = 0; i < size; i++) {
		phandle = fdt32_to_cpu(*list++);

		config_node = fdt_node_offset_by_phandle(fdt, phandle);
		if (config_node < 0) {
			dev_err(dev, "prop %s index %d invalid phandle\n",
				propname, i);
			return -EINVAL;
		}
		ret = uclass_get_device_by_of_offset(UCLASS_PINCONFIG,
						     config_node, &config);
		if (ret)
			return ret;

		ret = pinctrl_config_one(config);
		if (ret)
			return ret;
	}

	return 0;
}
コード例 #9
0
ファイル: gpio-uclass.c プロジェクト: eddyp/u-boot
static int _gpio_request_by_name_nodev(const void *blob, int node,
				       const char *list_name, int index,
				       struct gpio_desc *desc, int flags,
				       bool add_index)
{
	struct fdtdec_phandle_args args;
	int ret;

	desc->dev = NULL;
	desc->offset = 0;
	desc->flags = 0;
	ret = fdtdec_parse_phandle_with_args(blob, node, list_name,
					     "#gpio-cells", 0, index, &args);
	if (ret) {
		debug("%s: fdtdec_parse_phandle_with_args failed\n", __func__);
		goto err;
	}

	ret = uclass_get_device_by_of_offset(UCLASS_GPIO, args.node,
					     &desc->dev);
	if (ret) {
		debug("%s: uclass_get_device_by_of_offset failed\n", __func__);
		goto err;
	}
	ret = gpio_find_and_xlate(desc, &args);
	if (ret) {
		debug("%s: gpio_find_and_xlate failed\n", __func__);
		goto err;
	}
	ret = dm_gpio_requestf(desc, add_index ? "%s.%s%d" : "%s.%s",
			       fdt_get_name(blob, node, NULL),
			       list_name, index);
	if (ret) {
		debug("%s: dm_gpio_requestf failed\n", __func__);
		goto err;
	}
	ret = dm_gpio_set_dir_flags(desc, flags | desc->flags);
	if (ret) {
		debug("%s: dm_gpio_set_dir failed\n", __func__);
		goto err;
	}

	return 0;
err:
	debug("%s: Node '%s', property '%s', failed to request GPIO index %d: %d\n",
	      __func__, fdt_get_name(blob, node, NULL), list_name, index, ret);
	return ret;
}
コード例 #10
0
int reset_get_by_index(struct udevice *dev, int index,
		       struct reset_ctl *reset_ctl)
{
	struct fdtdec_phandle_args args;
	int ret;
	struct udevice *dev_reset;
	struct reset_ops *ops;

	debug("%s(dev=%p, index=%d, reset_ctl=%p)\n", __func__, dev, index,
	      reset_ctl);

	ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev->of_offset,
					     "resets", "#reset-cells", 0,
					     index, &args);
	if (ret) {
		debug("%s: fdtdec_parse_phandle_with_args failed: %d\n",
		      __func__, ret);
		return ret;
	}

	ret = uclass_get_device_by_of_offset(UCLASS_RESET, args.node,
					     &dev_reset);
	if (ret) {
		debug("%s: uclass_get_device_by_of_offset failed: %d\n",
		      __func__, ret);
		return ret;
	}
	ops = reset_dev_ops(dev_reset);

	reset_ctl->dev = dev_reset;
	if (ops->of_xlate)
		ret = ops->of_xlate(reset_ctl, &args);
	else
		ret = reset_of_xlate_default(reset_ctl, &args);
	if (ret) {
		debug("of_xlate() failed: %d\n", ret);
		return ret;
	}

	ret = ops->request(reset_ctl);
	if (ret) {
		debug("ops->request() failed: %d\n", ret);
		return ret;
	}

	return 0;
}
コード例 #11
0
static void serial_find_console_or_panic(void)
{
	struct udevice *dev;

#ifdef CONFIG_OF_CONTROL
	int node;

	/* Check for a chosen console */
	node = fdtdec_get_chosen_node(gd->fdt_blob, "stdout-path");
	if (node < 0)
		node = fdt_path_offset(gd->fdt_blob, "console");
	if (!uclass_get_device_by_of_offset(UCLASS_SERIAL, node, &dev)) {
		gd->cur_serial_dev = dev;
		return;
	}

	/*
	 * If the console is not marked to be bound before relocation, bind
	 * it anyway.
	 */
	if (node > 0 &&
	    !lists_bind_fdt(gd->dm_root, gd->fdt_blob, node, &dev)) {
		if (!device_probe(dev)) {
			gd->cur_serial_dev = dev;
			return;
		}
	}
#endif
	/*
	 * Try to use CONFIG_CONS_INDEX if available (it is numbered from 1!).
	 *
	 * Failing that, get the device with sequence number 0, or in extremis
	 * just the first serial device we can find. But we insist on having
	 * a console (even if it is silent).
	 */
#ifdef CONFIG_CONS_INDEX
#define INDEX (CONFIG_CONS_INDEX - 1)
#else
#define INDEX 0
#endif
	if (uclass_get_device_by_seq(UCLASS_SERIAL, INDEX, &dev) &&
	    uclass_get_device(UCLASS_SERIAL, INDEX, &dev) &&
	    (uclass_first_device(UCLASS_SERIAL, &dev) || !dev))
		panic("No serial driver found");
#undef INDEX
	gd->cur_serial_dev = dev;
}
コード例 #12
0
int power_domain_get(struct udevice *dev, struct power_domain *power_domain)
{
    struct fdtdec_phandle_args args;
    int ret;
    struct udevice *dev_power_domain;
    struct power_domain_ops *ops;

    debug("%s(dev=%p, power_domain=%p)\n", __func__, dev, power_domain);

    ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev->of_offset,
                                         "power-domains",
                                         "#power-domain-cells", 0, 0,
                                         &args);
    if (ret) {
        debug("%s: fdtdec_parse_phandle_with_args failed: %d\n",
              __func__, ret);
        return ret;
    }

    ret = uclass_get_device_by_of_offset(UCLASS_POWER_DOMAIN, args.node,
                                         &dev_power_domain);
    if (ret) {
        debug("%s: uclass_get_device_by_of_offset failed: %d\n",
              __func__, ret);
        return ret;
    }
    ops = power_domain_dev_ops(dev_power_domain);

    power_domain->dev = dev_power_domain;
    if (ops->of_xlate)
        ret = ops->of_xlate(power_domain, &args);
    else
        ret = power_domain_of_xlate_default(power_domain, &args);
    if (ret) {
        debug("of_xlate() failed: %d\n", ret);
        return ret;
    }

    ret = ops->request(power_domain);
    if (ret) {
        debug("ops->request() failed: %d\n", ret);
        return ret;
    }

    return 0;
}
コード例 #13
0
int mbox_get_by_index(struct udevice *dev, int index, struct mbox_chan *chan)
{
	struct fdtdec_phandle_args args;
	int ret;
	struct udevice *dev_mbox;
	struct mbox_ops *ops;

	debug("%s(dev=%p, index=%d, chan=%p)\n", __func__, dev, index, chan);

	ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev->of_offset,
					     "mboxes", "#mbox-cells", 0,
					     index, &args);
	if (ret) {
		debug("%s: fdtdec_parse_phandle_with_args failed: %d\n",
		      __func__, ret);
		return ret;
	}

	ret = uclass_get_device_by_of_offset(UCLASS_MAILBOX, args.node,
					     &dev_mbox);
	if (ret) {
		debug("%s: uclass_get_device_by_of_offset failed: %d\n",
		      __func__, ret);
		return ret;
	}
	ops = mbox_dev_ops(dev_mbox);

	chan->dev = dev_mbox;
	if (ops->of_xlate)
		ret = ops->of_xlate(chan, &args);
	else
		ret = mbox_of_xlate_default(chan, &args);
	if (ret) {
		debug("of_xlate() failed: %d\n", ret);
		return ret;
	}

	ret = ops->request(chan);
	if (ret) {
		debug("ops->request() failed: %d\n", ret);
		return ret;
	}

	return 0;
}
コード例 #14
0
ファイル: serial-uclass.c プロジェクト: OpenNoah/u-boot
static int serial_check_stdout(const void *blob, struct udevice **devp)
{
	int node;

	/* Check for a chosen console */
	node = fdtdec_get_chosen_node(blob, "stdout-path");
	if (node < 0) {
		const char *str, *p, *name;

		/*
		 * Deal with things like
		 *	stdout-path = "serial0:115200n8";
		 *
		 * We need to look up the alias and then follow it to the
		 * correct node.
		 */
		str = fdtdec_get_chosen_prop(blob, "stdout-path");
		if (str) {
			p = strchr(str, ':');
			name = fdt_get_alias_namelen(blob, str,
					p ? p - str : strlen(str));
			if (name)
				node = fdt_path_offset(blob, name);
		}
	}
	if (node < 0)
		node = fdt_path_offset(blob, "console");
	if (!uclass_get_device_by_of_offset(UCLASS_SERIAL, node, devp))
		return 0;

	/*
	 * If the console is not marked to be bound before relocation, bind it
	 * anyway.
	 */
	if (node > 0 && !lists_bind_fdt(gd->dm_root, offset_to_ofnode(node),
					devp)) {
		if (!device_probe(*devp))
			return 0;
	}

	return -ENODEV;
}
コード例 #15
0
ファイル: timer-uclass.c プロジェクト: frawang/u-boot
int notrace dm_timer_init(void)
{
	__maybe_unused const void *blob = gd->fdt_blob;
	struct udevice *dev = NULL;
	int node = -ENOENT;
	int ret;

	if (gd->timer)
		return 0;

#if !CONFIG_IS_ENABLED(OF_PLATDATA)
	/* Check for a chosen timer to be used for tick */
	node = fdtdec_get_chosen_node(blob, "tick-timer");
#endif
	if (node < 0) {
		/* No chosen timer, trying first available timer */
		ret = uclass_first_device_err(UCLASS_TIMER, &dev);
		if (ret)
			return ret;
	} else {
		if (uclass_get_device_by_of_offset(UCLASS_TIMER, node, &dev)) {
			/*
			 * If the timer is not marked to be bound before
			 * relocation, bind it anyway.
			 */
			if (node > 0 &&
			    !lists_bind_fdt(gd->dm_root, offset_to_ofnode(node),
					    &dev)) {
				ret = device_probe(dev);
				if (ret)
					return ret;
			}
		}
	}

	if (dev) {
		gd->timer = dev;
		return 0;
	}

	return -ENODEV;
}
コード例 #16
0
ファイル: clk-uclass.c プロジェクト: Philippe12/u-boot-sunxi
int clk_get_by_index(struct udevice *dev, int index, struct clk *clk)
{
	int ret;
	struct fdtdec_phandle_args args;
	struct udevice *dev_clk;
	struct clk_ops *ops;

	debug("%s(dev=%p, index=%d, clk=%p)\n", __func__, dev, index, clk);

	assert(clk);
	ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev_of_offset(dev),
					     "clocks", "#clock-cells", 0, index,
					     &args);
	if (ret) {
		debug("%s: fdtdec_parse_phandle_with_args failed: err=%d\n",
		      __func__, ret);
		return ret;
	}

	ret = uclass_get_device_by_of_offset(UCLASS_CLK, args.node, &dev_clk);
	if (ret) {
		debug("%s: uclass_get_device_by_of_offset failed: err=%d\n",
		      __func__, ret);
		return ret;
	}

	clk->dev = dev_clk;

	ops = clk_dev_ops(dev_clk);

	if (ops->of_xlate)
		ret = ops->of_xlate(clk, &args);
	else
		ret = clk_of_xlate_default(clk, &args);
	if (ret) {
		debug("of_xlate() failed: %d\n", ret);
		return ret;
	}

	return clk_request(dev_clk, clk);
}
コード例 #17
0
int mrccache_get_region(struct udevice **devp, struct mrc_region *entry)
{
	const void *blob = gd->fdt_blob;
	int node, mrc_node;
	u32 reg[2];
	int ret;

	/* Find the flash chip within the SPI controller node */
	node = fdtdec_next_compatible(blob, 0, COMPAT_GENERIC_SPI_FLASH);
	if (node < 0)
		return -ENOENT;

	if (fdtdec_get_int_array(blob, node, "memory-map", reg, 2))
		return -FDT_ERR_NOTFOUND;
	entry->base = reg[0];

	/* Find the place where we put the MRC cache */
	mrc_node = fdt_subnode_offset(blob, node, "rw-mrc-cache");
	if (mrc_node < 0)
		return -EPERM;

	if (fdtdec_get_int_array(blob, mrc_node, "reg", reg, 2))
		return -FDT_ERR_NOTFOUND;
	entry->offset = reg[0];
	entry->length = reg[1];

	if (devp) {
		ret = uclass_get_device_by_of_offset(UCLASS_SPI_FLASH, node,
						     devp);
		debug("ret = %d\n", ret);
		if (ret)
			return ret;
	}

	return 0;
}
コード例 #18
0
static int sti_sysreset_probe(struct udevice *dev)
{
	struct sti_sysreset_priv *priv = dev_get_priv(dev);
	struct udevice *syscon;
	struct regmap *regmap;
	struct fdtdec_phandle_args syscfg_phandle;
	int ret;

	/* get corresponding syscon phandle */
	ret = fdtdec_parse_phandle_with_args(gd->fdt_blob, dev_of_offset(dev),
					     "st,syscfg", NULL, 0, 0,
					     &syscfg_phandle);
	if (ret < 0) {
		pr_err("Can't get syscfg phandle: %d\n", ret);
		return ret;
	}

	ret = uclass_get_device_by_of_offset(UCLASS_SYSCON,
					     syscfg_phandle.node,
					     &syscon);
	if (ret) {
		pr_err("%s: uclass_get_device_by_of_offset failed: %d\n",
		      __func__, ret);
		return ret;
	}

	regmap = syscon_get_regmap(syscon);
	if (!regmap) {
		pr_err("unable to get regmap for %s\n", syscon->name);
		return -ENODEV;
	}

	priv->base = regmap->base;

	return 0;
}
コード例 #19
0
ファイル: tegra.c プロジェクト: hallor/u-boot
static int tegra_lcd_ofdata_to_platdata(struct udevice *dev)
{
    struct tegra_lcd_priv *priv = dev_get_priv(dev);
    struct fdtdec_phandle_args args;
    const void *blob = gd->fdt_blob;
    int node = dev->of_offset;
    int front, back, ref;
    int panel_node;
    int rgb;
    int bpp, bit;
    int ret;

    priv->disp = (struct disp_ctlr *)dev_get_addr(dev);
    if (!priv->disp) {
        debug("%s: No display controller address\n", __func__);
        return -EINVAL;
    }

    rgb = fdt_subnode_offset(blob, node, "rgb");

    panel_node = fdtdec_lookup_phandle(blob, rgb, "nvidia,panel");
    if (panel_node < 0) {
        debug("%s: Cannot find panel information\n", __func__);
        return -EINVAL;
    }

    priv->width = fdtdec_get_int(blob, panel_node, "xres", -1);
    priv->height = fdtdec_get_int(blob, panel_node, "yres", -1);
    priv->pixel_clock = fdtdec_get_int(blob, panel_node, "clock", 0);
    if (!priv->pixel_clock || priv->width == -1 || priv->height == -1) {
        debug("%s: Pixel parameters missing\n", __func__);
        return -EINVAL;
    }

    back = fdtdec_get_int(blob, panel_node, "left-margin", -1);
    front = fdtdec_get_int(blob, panel_node, "right-margin", -1);
    ref = fdtdec_get_int(blob, panel_node, "hsync-len", -1);
    if ((back | front | ref) == -1) {
        debug("%s: Horizontal parameters missing\n", __func__);
        return -EINVAL;
    }

    /* Use a ref-to-sync of 1 always, and take this from the front porch */
    priv->horiz_timing[FDT_LCD_TIMING_REF_TO_SYNC] = 1;
    priv->horiz_timing[FDT_LCD_TIMING_SYNC_WIDTH] = ref;
    priv->horiz_timing[FDT_LCD_TIMING_BACK_PORCH] = back;
    priv->horiz_timing[FDT_LCD_TIMING_FRONT_PORCH] = front -
            priv->horiz_timing[FDT_LCD_TIMING_REF_TO_SYNC];
    debug_timing("horiz", priv->horiz_timing);

    back = fdtdec_get_int(blob, panel_node, "upper-margin", -1);
    front = fdtdec_get_int(blob, panel_node, "lower-margin", -1);
    ref = fdtdec_get_int(blob, panel_node, "vsync-len", -1);
    if ((back | front | ref) == -1) {
        debug("%s: Vertical parameters missing\n", __func__);
        return -EINVAL;
    }

    priv->vert_timing[FDT_LCD_TIMING_REF_TO_SYNC] = 1;
    priv->vert_timing[FDT_LCD_TIMING_SYNC_WIDTH] = ref;
    priv->vert_timing[FDT_LCD_TIMING_BACK_PORCH] = back;
    priv->vert_timing[FDT_LCD_TIMING_FRONT_PORCH] = front -
            priv->vert_timing[FDT_LCD_TIMING_REF_TO_SYNC];
    debug_timing("vert", priv->vert_timing);

    bpp = fdtdec_get_int(blob, panel_node, "nvidia,bits-per-pixel", -1);
    bit = ffs(bpp) - 1;
    if (bpp == (1 << bit))
        priv->log2_bpp = bit;
    else
        priv->log2_bpp = bpp;
    if (bpp == -1) {
        debug("%s: Pixel bpp parameters missing\n", __func__);
        return -EINVAL;
    }

    if (fdtdec_parse_phandle_with_args(blob, panel_node, "nvidia,pwm",
                                       "#pwm-cells", 0, 0, &args)) {
        debug("%s: Unable to decode PWM\n", __func__);
        return -EINVAL;
    }

    ret = uclass_get_device_by_of_offset(UCLASS_PWM, args.node, &priv->pwm);
    if (ret) {
        debug("%s: Unable to find PWM\n", __func__);
        return -EINVAL;
    }
    priv->pwm_channel = args.args[0];

    priv->cache_type = fdtdec_get_int(blob, panel_node, "nvidia,cache-type",
                                      FDT_LCD_CACHE_WRITE_BACK_FLUSH);

    /* These GPIOs are all optional */
    gpio_request_by_name_nodev(blob, panel_node,
                               "nvidia,backlight-enable-gpios", 0,
                               &priv->backlight_en, GPIOD_IS_OUT);
    gpio_request_by_name_nodev(blob, panel_node,
                               "nvidia,lvds-shutdown-gpios", 0,
                               &priv->lvds_shutdown, GPIOD_IS_OUT);
    gpio_request_by_name_nodev(blob, panel_node,
                               "nvidia,backlight-vdd-gpios", 0,
                               &priv->backlight_vdd, GPIOD_IS_OUT);
    gpio_request_by_name_nodev(blob, panel_node,
                               "nvidia,panel-vdd-gpios", 0,
                               &priv->panel_vdd, GPIOD_IS_OUT);

    if (fdtdec_get_int_array(blob, panel_node, "nvidia,panel-timings",
                             priv->panel_timings, FDT_LCD_TIMINGS))
        return -EINVAL;

    return 0;
}
コード例 #20
0
ファイル: stm32mp1.c プロジェクト: CogSystems/u-boot
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;
}
コード例 #21
0
ファイル: serial-uclass.c プロジェクト: bradbishop/u-boot
static void serial_find_console_or_panic(void)
{
	const void *blob = gd->fdt_blob;
	struct udevice *dev;
	int node;

	if (CONFIG_IS_ENABLED(OF_CONTROL) && blob) {
		/* Check for a chosen console */
		node = fdtdec_get_chosen_node(blob, "stdout-path");
		if (node < 0) {
			const char *str, *p, *name;

			/*
			 * Deal with things like
			 *	stdout-path = "serial0:115200n8";
			 *
			 * We need to look up the alias and then follow it to
			 * the correct node.
			 */
			str = fdtdec_get_chosen_prop(blob, "stdout-path");
			if (str) {
				p = strchr(str, ':');
				name = fdt_get_alias_namelen(blob, str,
						p ? p - str : strlen(str));
				if (name)
					node = fdt_path_offset(blob, name);
			}
		}
		if (node < 0)
			node = fdt_path_offset(blob, "console");
		if (!uclass_get_device_by_of_offset(UCLASS_SERIAL, node,
						    &dev)) {
			gd->cur_serial_dev = dev;
			return;
		}

		/*
		* If the console is not marked to be bound before relocation,
		* bind it anyway.
		*/
		if (node > 0 &&
		    !lists_bind_fdt(gd->dm_root, blob, node, &dev)) {
			if (!device_probe(dev)) {
				gd->cur_serial_dev = dev;
				return;
			}
		}
	}
	if (!SPL_BUILD || !CONFIG_IS_ENABLED(OF_CONTROL) || !blob) {
		/*
		* Try to use CONFIG_CONS_INDEX if available (it is numbered
		* from 1!).
		*
		* Failing that, get the device with sequence number 0, or in
		* extremis just the first serial device we can find. But we
		* insist on having a console (even if it is silent).
		*/
#ifdef CONFIG_CONS_INDEX
#define INDEX (CONFIG_CONS_INDEX - 1)
#else
#define INDEX 0
#endif
		if (!uclass_get_device_by_seq(UCLASS_SERIAL, INDEX, &dev) ||
		    !uclass_get_device(UCLASS_SERIAL, INDEX, &dev) ||
		    (!uclass_first_device(UCLASS_SERIAL, &dev) && dev)) {
			gd->cur_serial_dev = dev;
			return;
		}
#undef INDEX
	}

#ifdef CONFIG_REQUIRE_SERIAL_CONSOLE
	panic_str("No serial driver found");
#endif
}