Exemple #1
0
static int tps65090_decode_config(struct tps65090_config *config)
{
#ifdef CONFIG_OF_CONTROL
	const void *blob = gd->fdt_blob;
	int node, parent;
	int i2c_bus;

	node = fdtdec_next_compatible(blob, 0, COMPAT_TI_TPS65090);
	if (node < 0) {
		debug("%s: Node not found\n", __func__);
		return -1;
	}
	parent = fdt_parent_offset(blob, node);
	if (parent < 0) {
		debug("%s: Cannot find node parent\n", __func__);
		return -1;
	}
	i2c_bus = i2c_get_bus_num_fdt(blob, parent);
	if (i2c_bus < 0)
		return -1;
	config->bus = i2c_bus;
	config->addr = fdtdec_get_addr(blob, node, "reg");
#else
	config->bus = CONFIG_TPS65090_I2C_BUS;
	config->addr = TPS65090_I2C_ADDR;
#endif
	return 0;
}
Exemple #2
0
/**
 * Decode TPM configuration.
 *
 * @param dev	Returns a configuration of TPM device
 * @return 0 if ok, -1 on error
 */
static int tpm_decode_config(struct tpm *dev)
{
#ifdef CONFIG_OF_CONTROL
	const void *blob = gd->fdt_blob;
	int node, parent;
	int i2c_bus;

	node = fdtdec_next_compatible(blob, 0, COMPAT_INFINEON_SLB9635_TPM);
	if (node < 0) {
		node = fdtdec_next_compatible(blob, 0,
					      COMPAT_INFINEON_SLB9645_TPM);
	}
	if (node < 0) {
		debug("%s: Node not found\n", __func__);
		return -1;
	}
	parent = fdt_parent_offset(blob, node);
	if (parent < 0) {
		debug("%s: Cannot find node parent\n", __func__);
		return -1;
	}
	i2c_bus = i2c_get_bus_num_fdt(blob, parent);
	if (i2c_bus < 0)
		return -1;
	dev->i2c_bus = i2c_bus;
	dev->slave_addr = fdtdec_get_addr(blob, node, "reg");
#else
	dev->i2c_bus = CONFIG_INFINEON_TPM_I2C_BUS;
	dev->slave_addr = CONFIG_INFINEON_TPM_I2C_ADDR;
#endif
	return 0;
}
Exemple #3
0
int fdtparse_get_interrupt_parent(const void *fdt, int nodeoffset) {
    int len;
    const struct fdt_property *interrupt_parent;
    fdt32_t *cell;
    uint32_t parent_phandle;
    int parent_offset;

    /* Use "interrupt-parent" from node, or node's parent */
    do {
        interrupt_parent = fdt_get_property(fdt, nodeoffset,
                                            "interrupt-parent", &len);
    } while ((len < 0) &&
             (nodeoffset = fdt_parent_offset(fdt, nodeoffset)) >= 0);

    if (len < 0) {
        return len;
    }

    /* Cell must be big enough to hold phandle */
    if (len < sizeof(fdt32_t)) {
        return -FDT_ERR_BADPHANDLE;
    }

    cell = (fdt32_t *) interrupt_parent->data;
    parent_phandle = fdt32_to_cpu(cell[0]);
    parent_offset = fdt_node_offset_by_phandle(fdt, parent_phandle);
    if (parent_offset < 0) {
        return parent_offset;
    }

    return parent_offset;
}
Exemple #4
0
static void check_path(struct fdt_header *fdt, const char *path)
{
    char *parentpath;
    int nodeoffset, parentoffset, parentpathoffset, pathparentlen;

    pathparentlen = path_parent_len(path);
    parentpath = alloca(pathparentlen + 1);
    strncpy(parentpath, path, pathparentlen);
    parentpath[pathparentlen] = '\0';

    verbose_printf("Path: \"%s\"\tParent: \"%s\"\n", path, parentpath);

    nodeoffset = fdt_path_offset(fdt, path);
    if (nodeoffset < 0)
        FAIL("fdt_path_offset(%s): %s", path, fdt_strerror(nodeoffset));

    parentpathoffset = fdt_path_offset(fdt, parentpath);
    if (parentpathoffset < 0)
        FAIL("fdt_path_offset(%s): %s", parentpath,
             fdt_strerror(parentpathoffset));

    parentoffset = fdt_parent_offset(fdt, nodeoffset);
    if (parentoffset < 0)
        FAIL("fdt_parent_offset(): %s", fdt_strerror(parentoffset));

    if (parentoffset != parentpathoffset)
        FAIL("fdt_parent_offset() returns %d instead of %d",
             parentoffset, parentpathoffset);
}
int mkbp_tps65090_init(void)
{
	const void *blob = gd->fdt_blob;
	int node, parent;

	node = fdtdec_next_compatible(blob, 0, COMPAT_TI_TPS65090);
	if (node < 0) {
		debug("%s: Node not found\n", __func__);
		return -ENOENT;
	}
	parent = fdt_parent_offset(blob, node);
	if (parent < 0) {
		debug("%s: Cannot find node parent\n", __func__);
		return -1;
	}

	if (fdt_node_check_compatible(blob, parent,
			fdtdec_get_compatible(COMPAT_GOOGLE_MKBP))) {
		debug("%s: TPS65090 not behind MKBP\n", __func__);
		return -ENOENT;
	}

	mkbp_dev = board_get_mkbp_dev();
	if (!mkbp_dev) {
		debug("%s: no mkbp device: cannot init tps65090\n",
			__func__);
		return -1;
	}

	debug("%s: accessing tps65090 through MKBP\n", __func__);
	return 0;
}
status_t
of_get_next_device(int *_cookie, int root, const char *type, char *path,
                   size_t pathSize)
{
    int next;
    int err;

    int startoffset = *_cookie ? *_cookie : -1;

    // iterate by property value
    next = fdt_node_offset_by_prop_value(gFDT, startoffset, "device_type",
                                         type, strlen(type) + 1);
    TRACE(("of_get_next_device(c:%d, %d, '%s', %p, %zd) soffset=%d next=%d\n",
           *_cookie, root, type, path, pathSize, startoffset, fdt2of(next)));
    if (next < 0)
        return B_ENTRY_NOT_FOUND;

    // make sure root is the parent
    int parent = next;
    while (root && parent) {
        parent = fdt_parent_offset(gFDT, parent);
        if (parent == root)
            break;
        if (parent <= 0)
            return B_ENTRY_NOT_FOUND;
    }

    *_cookie = next;

    err = fdt_get_path(gFDT, next, path, pathSize);
    if (err < 0)
        return B_ERROR;

    return B_OK;
}
Exemple #7
0
/* Update portal containter to match LAW setup of portal in phy map */
void fdt_portal(void *blob, const char *compat, const char *container,
			u64 addr, u32 size)
{
	int off;

	off = fdt_node_offset_by_compatible(blob, -1, compat);
	if (off < 0)
		return ;

	off = fdt_parent_offset(blob, off);
	/* if non-zero assume we have a container */
	if (off > 0) {
		char buf[60];
		const char *p, *name;
		u32 *range;
		int len;

		/* fixup ranges */
		range = fdt_getprop_w(blob, off, "ranges", &len);
		if (range == NULL) {
			printf("ERROR: container for %s has no ranges", compat);
			return ;
		}

		range[0] = 0;
		if (len == 16) {
			range[1] = addr >> 32;
			range[2] = addr & 0xffffffff;
			range[3] = size;
		} else {
Exemple #8
0
static uint32_t get_adjusted_address_int(const char *dtb, int node, uint32_t addr)
{
	// iterate through the sr array, looking for a region where:
	// 	sr[n].soc_node is a parent of node
	// 	addr is within the required range
	// then call self with return addr - child_addr + parent_addr
	// or just addr if nothing found
	
	if(node == fdt_path_offset(dtb, "/"))
		return addr;

	for(int i = 0; i < sr_items; i++)
	{
		if(sr[i].soc_node == node)
		{
			if(addr >= sr[i].child_addr &&
					addr < (sr[i].child_addr + sr[i].length))
			{
				addr = addr - sr[i].child_addr + sr[i].parent_addr;
				break;
			}
		}
	}

	node = fdt_parent_offset(dtb, node);
	if(node >= 0)
		return get_adjusted_address_int(dtb, node, addr);
	else
		return addr;
}
Exemple #9
0
int fdt_get_resource(const void *fdt, int node, const char *property,
		     unsigned int index, struct fdt_resource *res)
{
	const fdt32_t *ptr, *end;
	int na, ns, len, parent;
	unsigned int i = 0;

	parent = fdt_parent_offset(fdt, node);
	if (parent < 0)
		return parent;

	na = fdt_address_cells(fdt, parent);
	ns = fdt_size_cells(fdt, parent);

	ptr = fdt_getprop(fdt, node, property, &len);
	if (!ptr)
		return len;

	end = ptr + len / sizeof(*ptr);

	while (ptr + na + ns <= end) {
		if (i == index) {
			res->start = res->end = fdtdec_get_number(ptr, na);
			res->end += fdtdec_get_number(&ptr[na], ns) - 1;
			return 0;
		}

		ptr += na + ns;
		i++;
	}

	return -FDT_ERR_NOTFOUND;
}
Exemple #10
0
static uint32_t get_adjusted_address(const char *dtb, int node, uint32_t addr)
{
	node = fdt_parent_offset(dtb, node);
	if(node >= 0)
		return get_adjusted_address_int(dtb, node, addr);
	else
		return addr;
}
Exemple #11
0
/* FIXME: Optimize.  */
int32_t dt_nr_cells(void *fdt, int node, const char *name)
{
	const int32_t *nr_cells;

	node = fdt_parent_offset(fdt, node);
	do {
		int lenp;
		nr_cells = dt_get_property(fdt, node, name, &lenp);
		if (nr_cells) {
			return fdt32_to_cpu(*nr_cells);
		}

		node = fdt_parent_offset(fdt, node);
	} while (node >= 0);

	return -1;
}
Exemple #12
0
/**
 * Decode EC interface details from the device tree and allocate a suitable
 * device.
 *
 * @param blob		Device tree blob
 * @param node		Node to decode from
 * @param devp		Returns a pointer to the new allocated device
 * @return 0 if ok, -1 on error
 */
static int cros_ec_decode_fdt(const void *blob, int node,
		struct cros_ec_dev **devp)
{
	enum fdt_compat_id compat;
	struct cros_ec_dev *dev;
	int parent;

	/* See what type of parent we are inside (this is expensive) */
	parent = fdt_parent_offset(blob, node);
	if (parent < 0) {
		debug("%s: Cannot find node parent\n", __func__);
		return -1;
	}

	dev = &static_dev;
	dev->node = node;
	dev->parent_node = parent;

	compat = fdtdec_lookup(blob, parent);
	switch (compat) {
#ifdef CONFIG_CROS_EC_SPI
	case COMPAT_SAMSUNG_EXYNOS_SPI:
		dev->interface = CROS_EC_IF_SPI;
		if (cros_ec_spi_decode_fdt(dev, blob))
			return -1;
		break;
#endif
#ifdef CONFIG_CROS_EC_I2C
	case COMPAT_SAMSUNG_S3C2440_I2C:
		dev->interface = CROS_EC_IF_I2C;
		if (cros_ec_i2c_decode_fdt(dev, blob))
			return -1;
		break;
#endif
#ifdef CONFIG_CROS_EC_LPC
	case COMPAT_INTEL_LPC:
		dev->interface = CROS_EC_IF_LPC;
		break;
#endif
#ifdef CONFIG_CROS_EC_SANDBOX
	case COMPAT_SANDBOX_HOST_EMULATION:
		dev->interface = CROS_EC_IF_SANDBOX;
		break;
#endif
	default:
		debug("%s: Unknown compat id %d\n", __func__, compat);
		return -1;
	}

	fdtdec_decode_gpio(blob, node, "ec-interrupt", &dev->ec_int);
	dev->optimise_flash_write = fdtdec_get_bool(blob, node,
						    "optimise-flash-write");
	*devp = dev;

	return 0;
}
int board_usb_init(int index, enum usb_init_type init)
{
	int node, phy_node;
	const char *mode;
	bool matched = false;
	const void *blob = gd->fdt_blob;
	u32 grf_phy_offset;

	/* find the usb_otg node */
	node = fdt_node_offset_by_compatible(blob, -1,
					"rockchip,rk3288-usb");

	while (node > 0) {
		mode = fdt_getprop(blob, node, "dr_mode", NULL);
		if (mode && strcmp(mode, "otg") == 0) {
			matched = true;
			break;
		}

		node = fdt_node_offset_by_compatible(blob, node,
					"rockchip,rk3288-usb");
	}
	if (!matched) {
		debug("Not found usb_otg device\n");
		return -ENODEV;
	}
	rk3288_otg_data.regs_otg = fdtdec_get_addr(blob, node, "reg");

	node = fdtdec_lookup_phandle(blob, node, "phys");
	if (node <= 0) {
		debug("Not found usb phy device\n");
		return -ENODEV;
	}

	phy_node = fdt_parent_offset(blob, node);
	if (phy_node <= 0) {
		debug("Not found usb phy device\n");
		return -ENODEV;
	}

	rk3288_otg_data.phy_of_node = phy_node;
	grf_phy_offset = fdtdec_get_addr(blob, node, "reg");

	/* find the grf node */
	node = fdt_node_offset_by_compatible(blob, -1,
					"rockchip,rk3288-grf");
	if (node <= 0) {
		debug("Not found grf device\n");
		return -ENODEV;
	}
	rk3288_otg_data.regs_phy = grf_phy_offset +
				fdtdec_get_addr(blob, node, "reg");

	return dwc2_udc_probe(&rk3288_otg_data);
}
Exemple #14
0
/* Return the parent of this node or 0. */
static phandle_t
ofw_fdt_parent(ofw_t ofw, phandle_t node)
{
	int offset, paroffset;

	offset = fdt_phandle_offset(node);
	if (offset < 0)
		return (0);

	paroffset = fdt_parent_offset(fdtp, offset);
	return (fdt_offset_phandle(paroffset));
}
Exemple #15
0
static int rk808_parse_dt(const void* blob)
{
	int node, parent, nd;
	u32 i2c_bus_addr, bus;
	int ret;
	fdt_addr_t addr;
	struct fdt_gpio_state gpios[2];
	node = fdt_node_offset_by_compatible(blob,
					0, COMPAT_ROCKCHIP_RK808);
	if (node < 0) {
		printf("can't find dts node for rk808\n");
		return -ENODEV;
	}

	if (!fdt_device_is_available(blob,node)) {
		debug("device rk808 is disabled\n");
		return -1;
	}
	
	addr = fdtdec_get_addr(blob, node, "reg");
	fdtdec_decode_gpios(blob, node, "gpios", gpios, 2);
	
	parent = fdt_parent_offset(blob, node);
	if (parent < 0) {
		debug("%s: Cannot find node parent\n", __func__);
		return -1;
	}
	i2c_bus_addr = fdtdec_get_addr(blob, parent, "reg");
	bus = i2c_get_bus_num_fdt(i2c_bus_addr);
	ret = rk808_i2c_probe(bus, addr);
	if (ret < 0) {
		debug("pmic rk808 i2c probe failed\n");
		return ret;
	}
	
	nd = fdt_get_regulator_node(blob, node);
	if (nd < 0)
		printf("%s: Cannot find regulators\n", __func__);
	else
		fdt_regulator_match(blob, nd, rk808_reg_matches,
					RK808_NUM_REGULATORS);
	rk808.pmic = pmic_alloc();
	rk808.node = node;
	rk808.pmic->hw.i2c.addr = addr;
	rk808.pmic->bus = bus;
	rk808.pwr_hold.gpio = rk_gpio_base_to_bank(gpios[1].gpio & RK_GPIO_BANK_MASK) | 
				(gpios[1].gpio & RK_GPIO_PIN_MASK);
	rk808.pwr_hold.flags = !(gpios[1].flags  & OF_GPIO_ACTIVE_LOW);
	debug("rk808 i2c_bus:%d addr:0x%02x\n", rk808.pmic->bus,
		rk808.pmic->hw.i2c.addr);
	return 0;
	 
}
int pmic_init(unsigned char bus)
{
	static const char name[] = "MAX77686_PMIC";
	
    //struct pmic *p = pmic_alloc();
#ifdef CONFIG_OF_CONTROL
	const void *blob = gd->fdt_blob;
	int node, parent, tmp;
#endif

	//if (!p) {
    //	printf("%s: POWER allocation error!\n", __func__);
	//	return -ENOMEM;
	//}

#ifdef CONFIG_OF_CONTROL
	node = fdtdec_next_compatible(blob, 0, COMPAT_MAXIM_MAX77686_PMIC);
	if (node < 0) {
		debug("PMIC: No node for PMIC Chip in device tree\n");
		debug("node = %d\n", node);
		return -1;
	}

	parent = fdt_parent_offset(blob, node);
	if (parent < 0) {
		debug("%s: Cannot find node parent\n", __func__);
		return -1;
	}

	/* tmp since p->bus is unsigned */
	tmp = i2c_get_bus_num_fdt(parent);
	if (tmp < 0) {
		debug("%s: Cannot find I2C bus\n", __func__);
		return -1;
	}
	//p->bus = tmp;
	//p->hw.i2c.addr = fdtdec_get_int(blob, node, "reg", 9);
	 fdtdec_get_int(blob, node, "reg", 9);
#else
	p->bus = bus;
	p->hw.i2c.addr = MAX77686_I2C_ADDR;
#endif

	//p->name = name;
	//p->interface = PMIC_I2C;
	//p->number_of_regs = PMIC_NUM_OF_REGS;
	//p->hw.i2c.tx_num = 1;

	puts("Board PMIC init\n");

	return 0;
}
Exemple #17
0
fdt_addr_t fdtdec_get_addr_size_auto_noparent(const void *blob, int node,
		const char *prop_name, int index, fdt_size_t *sizep)
{
	int parent;

	debug("%s: ", __func__);

	parent = fdt_parent_offset(blob, node);
	if (parent < 0) {
		debug("(no parent found)\n");
		return FDT_ADDR_T_NONE;
	}

	return fdtdec_get_addr_size_auto_parent(blob, parent, node, prop_name,
						index, sizep);
}
int ricoh619_parse_dt(const void* blob)
{
	int node, parent, nd;
	u32 i2c_bus_addr, bus;
	int ret;
	fdt_addr_t addr;
	node = fdt_node_offset_by_compatible(blob, 0,
					COMPAT_RICOH_RICOH619);
	if (node < 0) {
		printf("can't find dts node for ricoh619\n");
		return -ENODEV;
	}

	if (!fdt_device_is_available(blob,node)) {
		debug("device ricoh619 is disabled\n");
		return -1;
	}
	
	addr = fdtdec_get_addr(blob, node, "reg");
	parent = fdt_parent_offset(blob, node);
	if (parent < 0) {
		debug("%s: Cannot find node parent\n", __func__);
		return -1;
	}
	i2c_bus_addr = fdtdec_get_addr(blob, parent, "reg");
	bus = i2c_get_bus_num_fdt(i2c_bus_addr);
	ret = ricoh619_i2c_probe(bus, addr);
	if (ret < 0) {
		debug("pmic ricoh619 i2c probe failed\n");
		return ret;
	}
	nd = fdt_get_regulator_node(blob, node);
	if (nd < 0)
		printf("%s: Cannot find regulators\n", __func__);
	else
		fdt_regulator_match(blob, nd, ricoh619_regulator_matches,
					RICOH619_NUM_REGULATORS);
	ricoh619.pmic = pmic_alloc();
	ricoh619.node = node;
	ricoh619.pmic->hw.i2c.addr = addr;
	ricoh619.pmic->bus = bus;
	debug("ricoh619 i2c_bus:%d addr:0x%02x\n", ricoh619.pmic->bus,
		ricoh619.pmic->hw.i2c.addr);
	return 0;
	 
}
Exemple #19
0
int tps65090_init(void)
{
	struct pmic *p;
	int bus;
	int addr;
	const void *blob = gd->fdt_blob;
	int node, parent;

	node = fdtdec_next_compatible(blob, 0, COMPAT_TI_TPS65090);
	if (node < 0) {
		debug("PMIC: No node for PMIC Chip in device tree\n");
		debug("node = %d\n", node);
		return -ENODEV;
	}

	parent = fdt_parent_offset(blob, node);
	if (parent < 0) {
		debug("%s: Cannot find node parent\n", __func__);
		return -EINVAL;
	}

	bus = i2c_get_bus_num_fdt(parent);
	if (p->bus < 0) {
		debug("%s: Cannot find I2C bus\n", __func__);
		return -ENOENT;
	}
	addr = fdtdec_get_int(blob, node, "reg", TPS65090_I2C_ADDR);
	p = pmic_alloc();
	if (!p) {
		printf("%s: POWER allocation error!\n", __func__);
		return -ENOMEM;
	}

	p->name = TPS65090_NAME;
	p->bus = bus;
	p->interface = PMIC_I2C;
	p->number_of_regs = TPS65090_NUM_REGS;
	p->hw.i2c.addr = addr;
	p->hw.i2c.tx_num = 1;
	p->chrg = &power_chrg_pmic_ops;

	puts("TPS65090 PMIC init\n");

	return 0;
}
Exemple #20
0
int main(int argc, char *argv[])
{
    void *fdt;
    int err;

    test_init(argc, argv);
    fdt = load_blob_arg(argc, argv);

    check_path(fdt, "/subnode@1");
    check_path(fdt, "/subnode@2");
    check_path(fdt, "/subnode@1/subsubnode");
    check_path(fdt, "/subnode@2/subsubnode@0");
    err = fdt_parent_offset(fdt, 0);
    if (err != -FDT_ERR_NOTFOUND)
        FAIL("fdt_parent_offset(/) returns %d instead of "
             "-FDT_ERR_NOTFOUND", err);

    PASS();
}
Exemple #21
0
fdt_addr_t fdtdec_get_addr_size(const void *blob, int node,
		const char *prop_name, fdt_size_t *sizep)
{
	const fdt32_t *ptr, *end;
	int parent, na, ns, len;
	fdt_addr_t addr;

	debug("%s: %s: ", __func__, prop_name);

	parent = fdt_parent_offset(blob, node);
	if (parent < 0) {
		debug("(no parent found)\n");
		return FDT_ADDR_T_NONE;
	}

	na = fdt_address_cells(blob, parent);
	ns = fdt_size_cells(blob, parent);

	ptr = fdt_getprop(blob, node, prop_name, &len);
	if (!ptr) {
		debug("(not found)\n");
		return FDT_ADDR_T_NONE;
	}

	end = ptr + len / sizeof(*ptr);

	if (ptr + na + ns > end) {
		debug("(not enough data: expected %d bytes, got %d bytes)\n",
		      (na + ns) * 4, len);
		return FDT_ADDR_T_NONE;
	}

	addr = fdtdec_get_number(ptr, na);

	if (sizep) {
		*sizep = fdtdec_get_number(ptr + na, ns);
		debug("addr=%pa, size=%pa\n", &addr, sizep);
	} else {
		debug("%pa\n", &addr);
	}

	return addr;
}
Exemple #22
0
/* We currently assume a fixed address/size.  Enforce that here.  */
static void check_cells(const void *dt, int node, int address, int size)
{
    const struct fdt_property *p;
    int parent;
    int len;
    int n;

    parent = fdt_parent_offset(dt, node);
    if (node < 0) {
        fprintf(stderr, "missing parent node for %s\n",
                fdt_get_name(dt, node, NULL));
        exit(1);
    }
    p = fdt_get_property(dt, parent, "#address-cells", &len);
    if (!p || len != 4) {
        fprintf(stderr,
                "Invalid or missing #address-cells for %s\n",
                fdt_get_name(dt, node, NULL));
        exit(1);
    }
    n = fdt32_to_cpu(*(uint32_t *)p->data);
    if (n != address) {
        fprintf(stderr,
                "Incorrect #address-cells for %s (expected %d got %d)\n",
                fdt_get_name(dt, node, NULL), address, n);
        exit(1);
    }
    p = fdt_get_property(dt, parent, "#size-cells", &len);
    if (!p || len != 4) {
        fprintf(stderr,
                "Invalid or missing #size-cells for %s\n",
                fdt_get_name(dt, node, NULL));
        exit(1);
    }
    n = fdt32_to_cpu(*(uint32_t *)p->data);
    if (n != size) {
        fprintf(stderr,
                "Incorrect #size-cells for %s (expected %d got %d)\n",
                fdt_get_name(dt, node, NULL), size, n);
        exit(1);
    }
}
Exemple #23
0
/* Verify parent MPU6000 exists */
static int mpu6000_accel_probe(const char *name) {
    const void *blob = fdtparse_get_blob();
    int offset, parent_offset, ret;
    char *parent;
    struct obj *parent_obj;

    offset = fdt_path_offset(blob, name);
    if (offset < 0) {
        return 0;
    }

    if (fdt_node_check_compatible(blob, offset, MPU6000_ACCEL_COMPAT)) {
        return 0;
    }

    parent_offset = fdt_parent_offset(blob, offset);
    if (parent_offset < 0) {
        return 0;
    }

    parent = fdtparse_get_path(blob, parent_offset);
    if (!parent) {
        return 0;
    }

    /* Attempt to get parent MPU6000 */
    parent_obj = device_get(parent);
    if (parent_obj) {
        /* Found it!  Good to go! */
        device_put(parent_obj);
        ret = 1;
    }
    else {
        /* No MPU6000, no MPU6000 accelerometer */
        ret = 0;
    }

    free(parent);

    return ret;
}
Exemple #24
0
paddr_t _fdt_reg_base_address(const void *fdt, int offs)
{
	const void *reg;
	int ncells;
	int len;
	int parent;

	parent = fdt_parent_offset(fdt, offs);
	if (parent < 0)
		return (paddr_t)-1;

	reg = fdt_getprop(fdt, offs, "reg", &len);
	if (!reg)
		return (paddr_t)-1;

	ncells = fdt_address_cells(fdt, parent);
	if (ncells < 0)
		return (paddr_t)-1;

	return _fdt_read_paddr(reg, ncells);
}
Exemple #25
0
static uint64
fdt_get_range_offset(const void* fdt, int32 node)
{
	// Obtain the offset of the device by searching
	// for the first ranges start in parents.

	// It could be possible that there are multiple
	// offset ranges in several parents + children.
	// Lets hope that no system designer is that insane.
	int depth = fdt_node_depth(fdt, node);
	int32 examineNode = node;
	uint64 pathOffset = 0x0;

	while (depth > 0) {
		int len;
		const void* prop;
		prop = fdt_getprop(fdt, examineNode, "ranges", &len);
		if (prop) {
			int32 regAddressCells = 1;
			int32 regSizeCells = 1;
			fdt_get_cell_count(fdt, examineNode, regAddressCells, regSizeCells);

			const uint32 *p = (const uint32 *)prop;
			// All we are interested in is the start offset
			if (regAddressCells == 2)
				pathOffset = fdt64_to_cpu(*(uint64_t *)p);
			else
				pathOffset = fdt32_to_cpu(*(uint32_t *)p);
			break;
		}
		int32 parentNode = fdt_parent_offset(fdt, examineNode);
		depth = fdt_node_depth(fdt, parentNode);
		examineNode = parentNode;
	}

	TRACE("%s: range offset: 0x%" B_PRIx64 "\n", __func__, pathOffset);

	return pathOffset;
}
Exemple #26
0
ssize_t _fdt_reg_size(const void *fdt, int offs)
{
	const uint32_t *reg;
	uint32_t sz;
	int n;
	int len;
	int parent;

	parent = fdt_parent_offset(fdt, offs);
	if (parent < 0)
		return (paddr_t)-1;

	reg = (const uint32_t *)fdt_getprop(fdt, offs, "reg", &len);
	if (!reg)
		return -1;

	n = fdt_address_cells(fdt, parent);
	if (n < 1 || n > 2)
		return -1;

	reg += n;

	n = fdt_size_cells(fdt, parent);
	if (n < 1 || n > 2)
		return -1;

	sz = fdt32_to_cpu(*reg);
	if (n == 2) {
		if (sz)
			return -1;
		reg++;
		sz = fdt32_to_cpu(*reg);
	}

	return sz;
}
Exemple #27
0
/*
 * fdt_get_reg - Fill buffer by information from DT
 */
static phys_size_t fdt_get_reg(const void *fdt, int nodeoffset, void *buf,
			       const u32 *cell, int n)
{
	int i = 0, b, banks;
	int parent_offset = fdt_parent_offset(fdt, nodeoffset);
	int address_cells = fdt_address_cells(fdt, parent_offset);
	int size_cells = fdt_size_cells(fdt, parent_offset);
	char *p = buf;
	phys_addr_t val;
	phys_size_t vals;

	debug("%s: addr_cells=%x, size_cell=%x, buf=%p, cell=%p\n",
	      __func__, address_cells, size_cells, buf, cell);

	/* Check memory bank setup */
	banks = n % (address_cells + size_cells);
	if (banks)
		panic("Incorrect memory setup cells=%d, ac=%d, sc=%d\n",
		      n, address_cells, size_cells);

	banks = n / (address_cells + size_cells);

	for (b = 0; b < banks; b++) {
		debug("%s: Bank #%d:\n", __func__, b);
		if (address_cells == 2) {
			val = cell[i + 1];
			val <<= 32;
			val |= cell[i];
			val = fdt64_to_cpu(val);
			debug("%s: addr64=%llx, ptr=%p, cell=%p\n",
			      __func__, val, p, &cell[i]);
			*(phys_addr_t *)p = val;
		} else {
			debug("%s: addr32=%x, ptr=%p\n",
			      __func__, fdt32_to_cpu(cell[i]), p);
			*(phys_addr_t *)p = fdt32_to_cpu(cell[i]);
		}
		p += sizeof(phys_addr_t);
		i += address_cells;

		debug("%s: pa=%p, i=%x, size=%zu\n", __func__, p, i,
		      sizeof(phys_addr_t));

		if (size_cells == 2) {
			vals = cell[i + 1];
			vals <<= 32;
			vals |= cell[i];
			vals = fdt64_to_cpu(vals);

			debug("%s: size64=%llx, ptr=%p, cell=%p\n",
			      __func__, vals, p, &cell[i]);
			*(phys_size_t *)p = vals;
		} else {
			debug("%s: size32=%x, ptr=%p\n",
			      __func__, fdt32_to_cpu(cell[i]), p);
			*(phys_size_t *)p = fdt32_to_cpu(cell[i]);
		}
		p += sizeof(phys_size_t);
		i += size_cells;

		debug("%s: ps=%p, i=%x, size=%zu\n",
		      __func__, p, i, sizeof(phys_size_t));
	}

	/* Return the first address size */
	return *(phys_size_t *)((char *)buf + sizeof(phys_addr_t));
}
Exemple #28
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;
}
static void *fdt_wrapper_get_parent(const void *devp)
{
	return offset_devp(fdt_parent_offset(fdt, devp_offset(devp)));
}
Exemple #30
0
phys_addr_t
fdt_get_device_reg(const void* fdt, int node, bool physical)
{
	const void *prop = NULL;
	int len;
	uint64 baseDevice = 0x0;

	int32 regAddressCells = 1;
	int32 regSizeCells = 1;
	fdt_get_cell_count(fdt, node, regAddressCells, regSizeCells);

	// TODO: check for virtual-reg, and don't -= fdt_get_range_offset?

	// XXX: not sure #address-cells & #size-cells actually apply to virtual-reg
	if (!physical) {
		prop = fdt_getprop(fdt, node, "virtual-reg", &len);
		if (prop != NULL) {
			baseDevice = fdt32_to_cpu(*(uint32_t *)prop);
			return baseDevice;
		}
	}

	prop = fdt_getprop(fdt, node, "reg", &len);

	if (!prop) {
		dprintf("%s: reg property not found on node in FDT!\n", __func__);
		return 0;
	}

	const uint32 *p = (const uint32 *)prop;

	// soc base address cells
	if (regAddressCells == 2)
		baseDevice = fdt64_to_cpu(*(uint64_t *)p);
	else
		baseDevice = fdt32_to_cpu(*(uint32_t *)p);
	//p += regAddressCells;

	// subtract the range offset (X) on the parent node (ranges = X Y Z)
	baseDevice -= fdt_get_range_offset(fdt, node);

	// find the start of the parent (X) and add to base (regs = X Y)
	int parentNode = fdt_parent_offset(fdt, node);
	if (!parentNode)
		return baseDevice;

	fdt_get_cell_count(fdt, parentNode, regAddressCells, regSizeCells);
	prop = fdt_getprop(fdt, parentNode, "reg", &len);

	if (!prop)
		return baseDevice;
	p = (const uint32 *)prop;

	uint64 parentReg = 0x0;
	// soc base address cells
	if (regAddressCells == 2)
		parentReg = fdt64_to_cpu(*(uint64_t *)p);
	else
		parentReg = fdt32_to_cpu(*(uint32_t *)p);

	// add parent reg base to property
	baseDevice += parentReg;

	return baseDevice;
}