Ejemplo n.º 1
0
static int rockchip_dwmmc_ofdata_to_platdata(struct udevice *dev)
{
#if !CONFIG_IS_ENABLED(OF_PLATDATA)
	struct rockchip_dwmmc_priv *priv = dev_get_priv(dev);
	struct dwmci_host *host = &priv->host;

	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->get_mmc_clk = rockchip_dwmmc_get_mmc_clk;
	host->priv = dev;

	/* use non-removeable as sdcard and emmc as judgement */
	if (fdtdec_get_bool(gd->fdt_blob, dev->of_offset, "non-removable"))
		host->dev_index = 0;
	else
		host->dev_index = 1;

	priv->fifo_depth = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
				    "fifo-depth", 0);
	if (priv->fifo_depth < 0)
		return -EINVAL;
	priv->fifo_mode = fdtdec_get_bool(gd->fdt_blob, dev->of_offset,
					  "fifo-mode");
	if (fdtdec_get_int_array(gd->fdt_blob, dev->of_offset,
				 "clock-freq-min-max", priv->minmax, 2))
		return -EINVAL;
#endif
	return 0;
}
Ejemplo n.º 2
0
static int ftsdc010_mmc_ofdata_to_platdata(struct udevice *dev)
{
#if !CONFIG_IS_ENABLED(OF_PLATDATA)
	struct ftsdc_priv *priv = dev_get_priv(dev);
	struct ftsdc010_chip *chip = &priv->chip;
	chip->name = dev->name;
	chip->ioaddr = (void *)devfdt_get_addr(dev);
	chip->buswidth = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
					"bus-width", 4);
	chip->priv = dev;
	priv->fifo_depth = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
				    "fifo-depth", 0);
	priv->fifo_mode = fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev),
					  "fifo-mode");
	if (fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(dev),
			 "clock-freq-min-max", priv->minmax, 2)) {
		int val = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
				  "max-frequency", -EINVAL);
		if (val < 0)
			return val;

		priv->minmax[0] = 400000;  /* 400 kHz */
		priv->minmax[1] = val;
	} else {
		debug("%s: 'clock-freq-min-max' property was deprecated.\n",
		__func__);
	}
#endif
	chip->sclk = priv->minmax[1];
	chip->regs = chip->ioaddr;
	return 0;
}
Ejemplo n.º 3
0
static int atmel_qspi_ofdata_to_platdata(struct udevice *dev)
{
	struct atmel_qspi_platdata *plat = dev_get_platdata(dev);
	const void *blob = gd->fdt_blob;
	int node = dev->of_offset;
	u32 data[4];
	int ret, seq;

	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->membase = (void *)data[2];

	ret = fdtdec_get_alias_seq(blob, "spi", node, &seq);
	if (ret) {
		printf("Error: Can't get device ID (ret=%d)!\n", ret);
		return -ENODEV;
	}
	plat->dev_id = (unsigned int)seq;

	return 0;
}
Ejemplo n.º 4
0
int pwm_request(const void *blob, int node, const char *prop_name)
{
	int pwm_node;
	u32 data[3];

	if (fdtdec_get_int_array(blob, node, prop_name, data,
			ARRAY_SIZE(data))) {
		debug("%s: Cannot decode PWM property '%s'\n", __func__,
		      prop_name);
		return -1;
	}

	pwm_node = fdt_node_offset_by_phandle(blob, data[0]);
	if (pwm_node != local.pwm_node) {
		debug("%s: PWM property '%s' phandle %d not recognised"
		      "- expecting %d\n", __func__, prop_name, data[0],
		      local.pwm_node);
		return -1;
	}
	if (data[1] >= PWM_NUM_CHANNELS) {
		debug("%s: PWM property '%s': invalid channel %u\n", __func__,
		      prop_name, data[1]);
		return -1;
	}

	/*
	 * TODO: We could maintain a list of requests, but it might not be
	 * worth it for U-Boot.
	 */
	return data[1];
}
Ejemplo n.º 5
0
static int pic32_sdhci_probe(struct udevice *dev)
{
	struct sdhci_host *host = dev_get_priv(dev);
	const void *fdt = gd->fdt_blob;
	u32 f_min_max[2];
	fdt_addr_t addr;
	fdt_size_t size;
	int ret;

	addr = fdtdec_get_addr_size(fdt, dev->of_offset, "reg", &size);
	if (addr == FDT_ADDR_T_NONE)
		return -EINVAL;

	host->ioaddr	= ioremap(addr, size);
	host->name	= dev->name;
	host->quirks	= SDHCI_QUIRK_NO_HISPD_BIT | SDHCI_QUIRK_NO_CD;
	host->bus_width	= fdtdec_get_int(gd->fdt_blob, dev->of_offset,
					"bus-width", 4);

	ret = fdtdec_get_int_array(gd->fdt_blob, dev->of_offset,
				   "clock-freq-min-max", f_min_max, 2);
	if (ret) {
		printf("sdhci: clock-freq-min-max not found\n");
		return ret;
	}

	ret = add_sdhci(host, f_min_max[1], f_min_max[0]);
	if (ret)
		return ret;
	host->mmc->dev = dev;

	return 0;
}
Ejemplo n.º 6
0
static int rk3036_pinctrl_get_periph_id(struct udevice *dev,
					struct udevice *periph)
{
	u32 cell[3];
	int ret;

	ret = fdtdec_get_int_array(gd->fdt_blob, periph->of_offset,
				   "interrupts", cell, ARRAY_SIZE(cell));
	if (ret < 0)
		return -EINVAL;

	switch (cell[1]) {
	case 14:
		return PERIPH_ID_SDCARD;
	case 16:
		return PERIPH_ID_EMMC;
	case 20:
		return PERIPH_ID_UART0;
	case 21:
		return PERIPH_ID_UART1;
	case 22:
		return PERIPH_ID_UART2;
	case 23:
		return PERIPH_ID_SPI0;
	case 24:
		return PERIPH_ID_I2C0;
	case 25:
		return PERIPH_ID_I2C1;
	case 26:
		return PERIPH_ID_I2C2;
	case 30:
		return PERIPH_ID_PWM0;
	}
	return -ENOENT;
}
Ejemplo n.º 7
0
int fdtdec_decode_periph_id(const void *blob, int node)
{
	u32 cell[2];
	int err;

	err = fdtdec_get_int_array(blob, node, "clocks", cell,
				   ARRAY_SIZE(cell));
	if (err)
		return -1;

	return cell[1];
}
Ejemplo n.º 8
0
static int exynos5_pinmux_decode_periph_id(const void *blob, int node)
{
	int err;
	u32 cell[3];

	err = fdtdec_get_int_array(blob, node, "interrupts", cell,
					ARRAY_SIZE(cell));
	if (err)
		return PERIPH_ID_NONE;

	return cell[1];
}
Ejemplo n.º 9
0
static int fsl_qspi_ofdata_to_platdata(struct udevice *bus)
{
	struct reg_data {
		u32 addr;
		u32 size;
	} regs_data[2];
	struct fsl_qspi_platdata *plat = bus->platdata;
	const void *blob = gd->fdt_blob;
	int node = bus->of_offset;
	int ret, flash_num = 0, subnode;

	if (fdtdec_get_bool(blob, node, "big-endian"))
		plat->flags |= QSPI_FLAG_REGMAP_ENDIAN_BIG;

	ret = fdtdec_get_int_array(blob, node, "reg", (u32 *)regs_data,
				   sizeof(regs_data)/sizeof(u32));
	if (ret) {
		debug("Error: can't get base addresses (ret = %d)!\n", ret);
		return -ENOMEM;
	}

	/* Count flash numbers */
	fdt_for_each_subnode(blob, subnode, node)
		++flash_num;

	if (flash_num == 0) {
		debug("Error: Missing flashes!\n");
		return -ENODEV;
	}

	plat->speed_hz = fdtdec_get_int(blob, node, "spi-max-frequency",
					FSL_QSPI_DEFAULT_SCK_FREQ);
	plat->num_chipselect = fdtdec_get_int(blob, node, "num-cs",
					      FSL_QSPI_MAX_CHIPSELECT_NUM);

	plat->reg_base = regs_data[0].addr;
	plat->amba_base = regs_data[1].addr;
	plat->amba_total_size = regs_data[1].size;
	plat->flash_num = flash_num;

	debug("%s: regs=<0x%x> <0x%x, 0x%x>, max-frequency=%d, endianess=%s\n",
	      __func__,
	      plat->reg_base,
	      plat->amba_base,
	      plat->amba_total_size,
	      plat->speed_hz,
	      plat->flags & QSPI_FLAG_REGMAP_ENDIAN_BIG ? "be" : "le"
	      );

	return 0;
}
Ejemplo n.º 10
0
/**
 * Read a flash entry from the fdt
 *
 * @param blob		FDT blob
 * @param node		Offset of node to read
 * @param name		Name of node being read
 * @param entry		Place to put offset and size of this node
 * @return 0 if ok, -ve on error
 */
int fdtdec_read_fmap_entry(const void *blob, int node, const char *name,
			   struct fmap_entry *entry)
{
	u32 reg[2];

	if (fdtdec_get_int_array(blob, node, "reg", reg, 2)) {
		debug("Node '%s' has bad/missing 'reg' property\n", name);
		return -FDT_ERR_NOTFOUND;
	}
	entry->offset = reg[0];
	entry->length = reg[1];

	return 0;
}
Ejemplo n.º 11
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;
}
static int rockchip_dwmmc_probe(struct udevice *dev)
{
	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
	struct rockchip_dwmmc_priv *priv = dev_get_priv(dev);
	struct dwmci_host *host = &priv->host;
	struct udevice *pwr_dev __maybe_unused;
	u32 minmax[2];
	int ret;
	int fifo_depth;

	ret = clk_get_by_index(dev, 0, &priv->clk);
	if (ret < 0)
		return ret;
	priv->periph = ret;

	if (fdtdec_get_int_array(gd->fdt_blob, dev->of_offset,
				 "clock-freq-min-max", minmax, 2))
		return -EINVAL;

	fifo_depth = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
				    "fifo-depth", 0);
	if (fifo_depth < 0)
		return -EINVAL;

	host->fifoth_val = MSIZE(0x2) |
		RX_WMARK(fifo_depth / 2 - 1) | TX_WMARK(fifo_depth / 2);

	if (fdtdec_get_bool(gd->fdt_blob, dev->of_offset, "fifo-mode"))
		host->fifo_mode = true;

#ifdef CONFIG_PWRSEQ
	/* Enable power if needed */
	ret = uclass_get_device_by_phandle(UCLASS_PWRSEQ, dev, "mmc-pwrseq",
					   &pwr_dev);
	if (!ret) {
		ret = pwrseq_set_power(pwr_dev, true);
		if (ret)
			return ret;
	}
#endif
	ret = add_dwmci(host, minmax[1], minmax[0]);
	if (ret)
		return ret;

	upriv->mmc = host->mmc;

	return 0;
}
Ejemplo n.º 13
0
static int simple_bus_post_bind(struct udevice *dev)
{
	u32 cell[3];
	int ret;

	ret = fdtdec_get_int_array(gd->fdt_blob, dev->of_offset, "ranges",
				   cell, ARRAY_SIZE(cell));
	if (!ret) {
		struct simple_bus_plat *plat = dev_get_uclass_platdata(dev);

		plat->base = cell[0];
		plat->target = cell[1];
		plat->size = cell[2];
	}

	return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false);
}
Ejemplo n.º 14
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];

	/* Use 500KHz as a suitable default */
	plat->max_hz = fdtdec_get_int(blob, node, "spi-max-frequency",
				      500000);

	/* 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;
	}

	/* 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);
	plat->sram_size = fdtdec_get_int(blob, node, "sram-size", 128);

	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;
}
Ejemplo n.º 15
0
int clk_get_by_index(struct udevice *dev, int index, struct clk *clk)
{
	int ret;
	u32 cell[2];

	if (index != 0)
		return -ENOSYS;
	assert(clk);
	ret = uclass_get_device(UCLASS_CLK, 0, &clk->dev);
	if (ret)
		return ret;
	ret = fdtdec_get_int_array(gd->fdt_blob, dev->of_offset, "clocks",
				   cell, 2);
	if (ret)
		return ret;
	clk->id = cell[1];
	return 0;
}
Ejemplo n.º 16
0
/**
 * Decode the panel information from the fdt.
 *
 * @param blob		fdt blob
 * @param config	structure to store fdt config into
 * @return 0 if ok, -ve on error
 */
static int fdt_decode_lcd(const void *blob, struct fdt_panel_config *config)
{
	int display_node;

	disp_config = tegra_display_get_config();
	if (!disp_config) {
		debug("%s: Display controller is not configured\n", __func__);
		return -1;
	}
	display_node = disp_config->panel_node;
	if (display_node < 0) {
		debug("%s: No panel configuration available\n", __func__);
		return -1;
	}

	config->pwm_channel = pwm_request(blob, display_node, "nvidia,pwm");
	if (config->pwm_channel < 0) {
		debug("%s: Unable to request PWM channel\n", __func__);
		return -1;
	}

	config->cache_type = fdtdec_get_int(blob, display_node,
					    "nvidia,cache-type",
					    FDT_LCD_CACHE_WRITE_BACK_FLUSH);

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

	return fdtdec_get_int_array(blob, display_node, "nvidia,panel-timings",
			config->panel_timings, FDT_LCD_TIMINGS);
}
Ejemplo n.º 17
0
static int pch_power_options(struct udevice *dev)
{
	int pwr_on_after_power_fail = MAINBOARD_POWER_OFF;
	const char *state;
	u32 enable[4];
	u16 reg16;
	int ret;

	dm_pci_read_config16(dev, GEN_PMCON_3, &reg16);
	reg16 &= 0xfffe;
	switch (pwr_on_after_power_fail) {
	case MAINBOARD_POWER_OFF:
		reg16 |= 1;
		state = "off";
		break;
	case MAINBOARD_POWER_ON:
		reg16 &= ~1;
		state = "on";
		break;
	case MAINBOARD_POWER_KEEP:
		reg16 &= ~1;
		state = "state keep";
		break;
	default:
		state = "undefined";
	}
	dm_pci_write_config16(dev, GEN_PMCON_3, reg16);
	debug("Set power %s after power failure.\n", state);

	/* GPE setup based on device tree configuration */
	ret = fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(dev),
				   "intel,gpe0-en", enable, ARRAY_SIZE(enable));
	if (ret)
		return -EINVAL;
	enable_all_gpe(enable[0], enable[1], enable[2], enable[3]);

	/* SMI setup based on device tree configuration */
	enable_alt_smi(dev, fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
					   "intel,alt-gp-smi-enable", 0));

	return 0;
}
Ejemplo n.º 18
0
static int rk322x_pinctrl_get_periph_id(struct udevice *dev,
					struct udevice *periph)
{
	u32 cell[3];
	int ret;

	ret = fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(periph),
				   "interrupts", cell, ARRAY_SIZE(cell));
	if (ret < 0)
		return -EINVAL;

	switch (cell[1]) {
	case 12:
		return PERIPH_ID_SDCARD;
	case 14:
		return PERIPH_ID_EMMC;
	case 36:
		return PERIPH_ID_I2C0;
	case 37:
		return PERIPH_ID_I2C1;
	case 38:
		return PERIPH_ID_I2C2;
	case 49:
		return PERIPH_ID_SPI0;
	case 50:
		return PERIPH_ID_PWM0;
	case 55:
		return PERIPH_ID_UART0;
	case 56:
		return PERIPH_ID_UART1;
	case 57:
		return PERIPH_ID_UART2;
#if CONFIG_IS_ENABLED(GMAC_ROCKCHIP)
	case 24:
		return PERIPH_ID_GMAC;
#endif
	}
	return -ENOENT;
}
Ejemplo n.º 19
0
/**
 * Read a flash entry from the fdt
 *
 * @param blob		FDT blob
 * @param node		Offset of node to read
 * @param name		Name of node being read
 * @param entry		Place to put offset and size of this node
 * @return 0 if ok, -ve on error
 */
int fdtdec_read_fmap_entry(const void *blob, int node, const char *name,
			   struct fmap_entry *entry)
{
	const char *prop;
	u32 reg[2];

	if (fdtdec_get_int_array(blob, node, "reg", reg, 2)) {
		debug("Node '%s' has bad/missing 'reg' property\n", name);
		return -FDT_ERR_NOTFOUND;
	}
	entry->offset = reg[0];
	entry->length = reg[1];
	entry->used = fdtdec_get_int(blob, node, "used", entry->length);
	prop = fdt_getprop(blob, node, "compress", NULL);
	entry->compress_algo = prop && !strcmp(prop, "lzo") ?
		FMAP_COMPRESS_LZO : FMAP_COMPRESS_NONE;
	prop = fdt_getprop(blob, node, "hash", &entry->hash_size);
	entry->hash_algo = prop ? FMAP_HASH_SHA256 : FMAP_HASH_NONE;
	entry->hash = (uint8_t *)prop;

	return 0;
}
static int pic32_pinctrl_get_periph_id(struct udevice *dev,
				       struct udevice *periph)
{
	int ret;
	u32 cell[2];

	ret = fdtdec_get_int_array(gd->fdt_blob, periph->of_offset,
				   "interrupts", cell, ARRAY_SIZE(cell));
	if (ret < 0)
		return -EINVAL;

	/* interrupt number */
	switch (cell[0]) {
	case 112 ... 114:
		return PERIPH_ID_UART1;
	case 145 ... 147:
		return PERIPH_ID_UART2;
	case 109 ... 111:
		return PERIPH_ID_SPI1;
	case 142 ... 144:
		return PERIPH_ID_SPI2;
	case 115 ... 117:
		return PERIPH_ID_I2C1;
	case 148 ... 150:
		return PERIPH_ID_I2C2;
	case 132 ... 133:
		return PERIPH_ID_USB;
	case 169:
		return PERIPH_ID_SQI;
	case 191:
		return PERIPH_ID_SDHCI;
	case 153:
		return PERIPH_ID_ETH;
	default:
		break;
	}

	return -ENOENT;
}
Ejemplo n.º 21
0
static int rk3288_pinctrl_get_periph_id(struct udevice *dev,
					struct udevice *periph)
{
#if !CONFIG_IS_ENABLED(OF_PLATDATA)
	u32 cell[3];
	int ret;

	ret = fdtdec_get_int_array(gd->fdt_blob, periph->of_offset,
				   "interrupts", cell, ARRAY_SIZE(cell));
	if (ret < 0)
		return -EINVAL;

	switch (cell[1]) {
	case 44:
		return PERIPH_ID_SPI0;
	case 45:
		return PERIPH_ID_SPI1;
	case 46:
		return PERIPH_ID_SPI2;
	case 60:
		return PERIPH_ID_I2C0;
	case 62: /* Note strange order */
		return PERIPH_ID_I2C1;
	case 61:
		return PERIPH_ID_I2C2;
	case 63:
		return PERIPH_ID_I2C3;
	case 64:
		return PERIPH_ID_I2C4;
	case 65:
		return PERIPH_ID_I2C5;
	case 103:
		return PERIPH_ID_HDMI;
	}
#endif

	return -ENOENT;
}
Ejemplo n.º 22
0
static int decode_timing_property(const void *blob, int node, const char *name,
				  struct timing_entry *result)
{
	int length, ret = 0;
	const u32 *prop;

	prop = fdt_getprop(blob, node, name, &length);
	if (!prop) {
		debug("%s: could not find property %s\n",
		      fdt_get_name(blob, node, NULL), name);
		return length;
	}

	if (length == sizeof(u32)) {
		result->typ = fdtdec_get_int(blob, node, name, 0);
		result->min = result->typ;
		result->max = result->typ;
	} else {
		ret = fdtdec_get_int_array(blob, node, name, &result->min, 3);
	}

	return ret;
}
Ejemplo n.º 23
0
static int decode_sromc(const void *blob, struct fdt_sromc *config)
{
	int err;
	int node;

	node = fdtdec_next_compatible(blob, 0, COMPAT_SAMSUNG_EXYNOS5_SROMC);
	if (node < 0) {
		debug("Could not find SROMC node\n");
		return node;
	}

	config->bank = fdtdec_get_int(blob, node, "bank", 0);
	config->width = fdtdec_get_int(blob, node, "width", 2);

	err = fdtdec_get_int_array(blob, node, "srom-timing", config->timing,
			FDT_SROM_TIMING_COUNT);
	if (err < 0) {
		debug("Could not decode SROMC configuration Error: %s\n",
		      fdt_strerror(err));
		return -FDT_ERR_NOTFOUND;
	}
	return 0;
}
static int _gpio_ich6_pinctrl_cfg_pin(s32 gpiobase, s32 iobase, int pin_node)
{
	u32 gpio_offset[2];
	int pad_offset;
	int val;
	int ret;
	const void *prop;

	/*
	 * GPIO node is not mandatory, so we only do the
	 * pinmuxing if the node exist.
	 */
	ret = fdtdec_get_int_array(gd->fdt_blob, pin_node, "gpio-offset",
			     gpio_offset, 2);
	if (!ret) {
		/* Do we want to force the GPIO mode? */
		prop = fdt_getprop(gd->fdt_blob, pin_node, "mode-gpio",
				      NULL);
		if (prop)
			_ich6_gpio_set_function(GPIO_USESEL_OFFSET
						(gpiobase) +
						gpio_offset[0],
						gpio_offset[1], 1);

		val =
		    fdtdec_get_int(gd->fdt_blob, pin_node, "direction", -1);
		if (val != -1)
			_ich6_gpio_set_direction(GPIO_IOSEL_OFFSET
						 (gpiobase) +
						 gpio_offset[0],
						 gpio_offset[1], val);

		val =
		    fdtdec_get_int(gd->fdt_blob, pin_node, "output-value", -1);
		if (val != -1)
			_ich6_gpio_set_value(GPIO_LVL_OFFSET(gpiobase)
					     + gpio_offset[0],
					     gpio_offset[1], val);
	}

	/* if iobase is present, let's configure the pad */
	if (iobase != -1) {
		int iobase_addr;

		/*
		 * The offset for the same pin for the IOBASE and GPIOBASE are
		 * different, so instead of maintaining a lookup table,
		 * the device tree should provide directly the correct
		 * value for both mapping.
		 */
		pad_offset =
		    fdtdec_get_int(gd->fdt_blob, pin_node, "pad-offset", -1);
		if (pad_offset == -1) {
			debug("%s: Invalid register io offset %d\n",
			      __func__, pad_offset);
			return -EINVAL;
		}

		/* compute the absolute pad address */
		iobase_addr = iobase + pad_offset;

		/*
		 * Do we need to set a specific function mode?
		 * If someone put also 'mode-gpio', this option will
		 * be just ignored by the controller
		 */
		val = fdtdec_get_int(gd->fdt_blob, pin_node, "mode-func", -1);
		if (val != -1)
			clrsetbits_le32(iobase_addr, IOPAD_MODE_MASK, val);

		/* Configure the pull-up/down if needed */
		val = fdtdec_get_int(gd->fdt_blob, pin_node, "pull-assign", -1);
		if (val != -1)
			clrsetbits_le32(iobase_addr,
					IOPAD_PULL_ASSIGN_MASK,
					val << IOPAD_PULL_ASSIGN_SHIFT);

		val =
		    fdtdec_get_int(gd->fdt_blob, pin_node, "pull-strength", -1);
		if (val != -1)
			clrsetbits_le32(iobase_addr,
					IOPAD_PULL_STRENGTH_MASK,
					val << IOPAD_PULL_STRENGTH_SHIFT);

		debug("%s: pad cfg [0x%x]: %08x\n", __func__, pad_offset,
		      readl(iobase_addr));
	}

	return 0;
}
Ejemplo n.º 25
0
/* VbExLegacy calls a payload (e.g. SeaBIOS) from an alternate CBFS
 * that lives in the RW section if CTRL-L is pressed at the dev screen.
 * FIXME: Right now no verification is done what so ever!
 */
int VbExLegacy(void)
{
	CbfsFile payload;
	int legacy_node, flash_node;
	u32 flash_base, legacy_offset, legacy_length;
	u32 reg[2];

	flash_node = fdt_path_offset(gd->fdt_blob, "/flash");
	if (flash_node < 0) {
		printf("Could not find /flash in FDT\n");
		return 1;
	}

	legacy_node = fdt_path_offset(gd->fdt_blob, "/flash/rw-legacy");
	if (!legacy_node) {
		printf("Could not find /flash/rw-legacy in FDT\n");
		return 1;
	}

	if (fdtdec_get_int_array(gd->fdt_blob, flash_node, "reg", reg, 2)) {
		printf("Error decoding reg property of /flash\n");
		return 1;
	}
	flash_base = reg[0];

	if (fdtdec_get_int_array(gd->fdt_blob, legacy_node, "reg", reg, 2)) {
		printf("Error decoding reg property of /flash/rw-legacy\n");
		return 1;
	}
	legacy_offset = reg[0];
	legacy_length = reg[1];

	/* Point to alternate CBFS */
	file_cbfs_init(flash_base + legacy_offset + legacy_length - 1);

	/* For debugging, show the contents of our CBFS */
	do_cbfs_ls(NULL, 0, 0, NULL);

	/* Look for a payload named "payload" */
	payload = file_cbfs_find("payload");
	if (!payload) {
		printf("No file \"payload\" found in CBFS.\n");
		return 1;
	}

	/* This is a minimalistic SELF parser.  */
	CbfsPayloadSegment *seg = payload->data;
	while (1) {
		void (*payload_entry)(void);
		void *src = payload->data + be32_to_cpu(seg->offset);
		void *dst = (void *)(unsigned long)be64_to_cpu(seg->load_addr);
		u32 src_len = be32_to_cpu(seg->len);
		u32 dst_len = be32_to_cpu(seg->mem_len);

		switch (seg->type) {
		case PAYLOAD_SEGMENT_CODE:
		case PAYLOAD_SEGMENT_DATA:
			printf("CODE/DATA: dst=%p dst_len=%d src=%p "
				"src_len=%d\n", dst, dst_len, src, src_len);
			if (be32_to_cpu(seg->compression) ==
						CBFS_COMPRESS_NONE) {
				memcpy(dst, src, src_len);
			} else
#ifdef CONFIG_LZMA
			if (be32_to_cpu(seg->compression) ==
						CBFS_COMPRESS_LZMA) {
				int ret;
				SizeT lzma_len = dst_len;
				ret = lzmaBuffToBuffDecompress(
					(unsigned char *)dst, &lzma_len,
					(unsigned char *)src, src_len);
				if (ret != SZ_OK) {
					printf("LZMA: Decompression failed. "
						"ret=%d.\n", ret);
					return 1;
				}
			} else
#endif
			{
				printf("Compression type %x not supported\n",
					be32_to_cpu(seg->compression));
				return 1;
			}
			break;
		case PAYLOAD_SEGMENT_BSS:
			printf("BSS: dst=%p len=%d\n", dst, dst_len);
			memset(dst, 0, dst_len);
			break;
		case PAYLOAD_SEGMENT_PARAMS:
			printf("PARAMS: skipped\n");
			break;
		case PAYLOAD_SEGMENT_ENTRY:
			board_final_cleanup();
			TlclSaveState();
			payload_entry = dst;
			payload_entry();
			return 0;
		default:
			printf("segment type %x not implemented. Exiting\n",
				seg->type);
			return 1;
		}
		seg++;
	}

	/* Make GCC happy. This point is never reached. */
	return 0;
}
Ejemplo n.º 26
0
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;
}
Ejemplo n.º 27
0
int exynos_dwmmc_init(const void *blob)
{
	int index, bus_width;
	int node_list[DWMMC_MAX_CH_NUM];
	int err = 0, dev_id, flag, count, i;
	u32 clksel_val, base, timing[3];

	count = fdtdec_find_aliases_for_id(blob, "mmc",
				COMPAT_SAMSUNG_EXYNOS5_DWMMC, node_list,
				DWMMC_MAX_CH_NUM);

	for (i = 0; i < count; i++) {
		int node = node_list[i];

		if (node <= 0)
			continue;

		/* Extract device id for each mmc channel */
		dev_id = pinmux_decode_periph_id(blob, node);

		/* Get the bus width from the device node */
		bus_width = fdtdec_get_int(blob, node, "samsung,bus-width", 0);
		if (bus_width <= 0) {
			debug("DWMMC: Can't get bus-width\n");
			return -1;
		}
		if (8 == bus_width)
			flag = PINMUX_FLAG_8BIT_MODE;
		else
			flag = PINMUX_FLAG_NONE;

		/* config pinmux for each mmc channel */
		err = exynos_pinmux_config(dev_id, flag);
		if (err) {
			debug("DWMMC not configured\n");
			return err;
		}

		index = dev_id - PERIPH_ID_SDMMC0;

		/* Get the base address from the device node */
		base = fdtdec_get_addr(blob, node, "reg");
		if (!base) {
			debug("DWMMC: Can't get base address\n");
			return -1;
		}
		/* Extract the timing info from the node */
		err = fdtdec_get_int_array(blob, node, "samsung,timing",
					timing, 3);
		if (err) {
			debug("Can't get sdr-timings for divider\n");
			return -1;
		}

		clksel_val = (DWMCI_SET_SAMPLE_CLK(timing[0]) |
				DWMCI_SET_DRV_CLK(timing[1]) |
				DWMCI_SET_DIV_RATIO(timing[2]));
		/* Initialise each mmc channel */
		err = exynos_dwmci_add_port(index, base, bus_width, clksel_val);
		if (err)
			debug("dwmmc Channel-%d init failed\n", index);
	}
	return 0;
}