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; }
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; }
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; }
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]; }
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; }
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; }
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]; }
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]; }
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; }
/** * 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; }
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; }
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); }
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; }
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; }
/** * 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); }
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, ®16); 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; }
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; }
/** * 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; }
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; }
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; }
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; }
/* 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; }
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; }
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; }