Example #1
0
int ofnode_decode_memory_region(ofnode config_node, const char *mem_type,
				const char *suffix, fdt_addr_t *basep,
				fdt_size_t *sizep)
{
	char prop_name[50];
	const char *mem;
	fdt_size_t size, offset_size;
	fdt_addr_t base, offset;
	ofnode node;

	if (!ofnode_valid(config_node)) {
		config_node = ofnode_path("/config");
		if (!ofnode_valid(config_node)) {
			debug("%s: Cannot find /config node\n", __func__);
			return -ENOENT;
		}
	}
	if (!suffix)
		suffix = "";

	snprintf(prop_name, sizeof(prop_name), "%s-memory%s", mem_type,
		 suffix);
	mem = ofnode_read_string(config_node, prop_name);
	if (!mem) {
		debug("%s: No memory type for '%s', using /memory\n", __func__,
		      prop_name);
		mem = "/memory";
	}

	node = ofnode_path(mem);
	if (!ofnode_valid(node)) {
		debug("%s: Failed to find node '%s'\n", __func__, mem);
		return -ENOENT;
	}

	/*
	 * Not strictly correct - the memory may have multiple banks. We just
	 * use the first
	 */
	if (ofnode_decode_region(node, "reg", &base, &size)) {
		debug("%s: Failed to decode memory region %s\n", __func__,
		      mem);
		return -EINVAL;
	}

	snprintf(prop_name, sizeof(prop_name), "%s-offset%s", mem_type,
		 suffix);
	if (ofnode_decode_region(config_node, prop_name, &offset,
				 &offset_size)) {
		debug("%s: Failed to decode memory region '%s'\n", __func__,
		      prop_name);
		return -EINVAL;
	}

	*basep = base + offset;
	*sizep = offset_size;

	return 0;
}
Example #2
0
static int fs_loader_ofdata_to_platdata(struct udevice *dev)
{
	const char *fs_loader_path;
	u32 phandlepart[2];

	fs_loader_path = ofnode_get_chosen_prop("firmware-loader");

	if (fs_loader_path) {
		ofnode fs_loader_node;

		fs_loader_node = ofnode_path(fs_loader_path);
		if (ofnode_valid(fs_loader_node)) {
			struct device_platdata *plat;
			plat = dev->platdata;

			if (!ofnode_read_u32_array(fs_loader_node,
						  "phandlepart",
						  phandlepart, 2)) {
				plat->phandlepart.phandle = phandlepart[0];
				plat->phandlepart.partition = phandlepart[1];
			}

			plat->mtdpart = (char *)ofnode_read_string(
					 fs_loader_node, "mtdpart");

			plat->ubivol = (char *)ofnode_read_string(
					 fs_loader_node, "ubivol");
		}
	}

	return 0;
}
Example #3
0
int soc_clk_ctl(const char *name, ulong *rate, enum clk_ctl_ops ctl)
{
	int ret;
	ulong mhz_rate, priv_rate;
	struct clk clk;

	/* Dummy fmeas device, just to be able to use standard clk_* api */
	struct udevice fmeas = {
		.name = "clk-fmeas",
		.node = ofnode_path("/clk-fmeas"),
	};

	ret = clk_get_by_name(&fmeas, name, &clk);
	if (ret) {
		pr_err("clock '%s' not found, err=%d\n", name, ret);
		return ret;
	}

	if (ctl & CLK_ON) {
		ret = clk_enable(&clk);
		if (ret && ret != -ENOSYS && ret != -ENOTSUPP)
			return ret;
	}

	if ((ctl & CLK_SET) && rate) {
		priv_rate = ctl & CLK_MHZ ? (*rate) * HZ_IN_MHZ : *rate;
		ret = clk_set_rate(&clk, priv_rate);
		if (ret)
			return ret;
	}

	if (ctl & CLK_OFF) {
		ret = clk_disable(&clk);
		if (ret) {
			pr_err("clock '%s' can't be disabled, err=%d\n", name, ret);
			return ret;
		}
	}

	priv_rate = clk_get_rate(&clk);

	clk_free(&clk);

	mhz_rate = ceil(priv_rate, HZ_IN_MHZ);

	if (ctl & CLK_MHZ)
		priv_rate = mhz_rate;

	if ((ctl & CLK_GET) && rate)
		*rate = priv_rate;

	if ((ctl & CLK_PRINT) && (ctl & CLK_MHZ))
		printf("HSDK: clock '%s' rate %lu MHz\n", name, priv_rate);
	else if (ctl & CLK_PRINT)
		printf("HSDK: clock '%s' rate %lu Hz\n", name, priv_rate);
	else
		debug("HSDK: clock '%s' rate %lu MHz\n", name, mhz_rate);

	return 0;
}
Example #4
0
/* Base test of register maps */
static int dm_test_regmap_base(struct unit_test_state *uts)
{
	struct udevice *dev;
	struct regmap *map;
	ofnode node;
	int i;

	ut_assertok(uclass_get_device(UCLASS_SYSCON, 0, &dev));
	map = syscon_get_regmap(dev);
	ut_assertok_ptr(map);
	ut_asserteq(1, map->range_count);
	ut_asserteq(0x10, map->ranges[0].start);
	ut_asserteq(4, map->ranges[0].size);
	ut_asserteq(0x10, map_to_sysmem(regmap_get_range(map, 0)));

	ut_assertok(uclass_get_device(UCLASS_SYSCON, 1, &dev));
	map = syscon_get_regmap(dev);
	ut_assertok_ptr(map);
	ut_asserteq(4, map->range_count);
	ut_asserteq(0x20, map->ranges[0].start);
	for (i = 0; i < 4; i++) {
		const unsigned long addr = 0x20 + 8 * i;

		ut_asserteq(addr, map->ranges[i].start);
		ut_asserteq(5 + i, map->ranges[i].size);
		ut_asserteq(addr, map_to_sysmem(regmap_get_range(map, i)));
	}

	/* Check that we can't pretend a different device is a syscon */
	ut_assertok(uclass_get_device(UCLASS_I2C, 0, &dev));
	map = syscon_get_regmap(dev);
	ut_asserteq_ptr(ERR_PTR(-ENOEXEC), map);

	/* A different device can be a syscon by using Linux-compat API */
	node = ofnode_path("/syscon@2");
	ut_assert(ofnode_valid(node));

	map = syscon_node_to_regmap(node);
	ut_assertok_ptr(map);
	ut_asserteq(4, map->range_count);
	ut_asserteq(0x40, map->ranges[0].start);
	for (i = 0; i < 4; i++) {
		const unsigned long addr = 0x40 + 8 * i;

		ut_asserteq(addr, map->ranges[i].start);
		ut_asserteq(5 + i, map->ranges[i].size);
		ut_asserteq(addr, map_to_sysmem(regmap_get_range(map, i)));
	}

	return 0;
}
Example #5
0
static int uclass_cpu_init(struct uclass *uc)
{
	struct udevice *dev;
	ofnode node;
	int ret;

	node = ofnode_path("/cpus");
	if (!ofnode_valid(node))
		return 0;

	ret = device_bind_driver_to_node(dm_root(), "cpu_bus", "cpus", node,
					 &dev);

	return ret;
}
Example #6
0
static void rk3399_force_power_on_reset(void)
{
	ofnode node;
	struct gpio_desc sysreset_gpio;

	debug("%s: trying to force a power-on reset\n", __func__);

	node = ofnode_path("/config");
	if (!ofnode_valid(node)) {
		debug("%s: no /config node?\n", __func__);
		return;
	}

	if (gpio_request_by_name_nodev(node, "sysreset-gpio", 0,
				       &sysreset_gpio, GPIOD_IS_OUT)) {
		debug("%s: could not find a /config/sysreset-gpio\n", __func__);
		return;
	}

	dm_gpio_set_value(&sysreset_gpio, 1);
}