int fdtdec_decode_display_timing(const void *blob, int parent, int index, struct display_timing *dt) { int i, node, timings_node; u32 val = 0; int ret = 0; timings_node = fdt_subnode_offset(blob, parent, "display-timings"); if (timings_node < 0) return timings_node; for (i = 0, node = fdt_first_subnode(blob, timings_node); node > 0 && i != index; node = fdt_next_subnode(blob, node)) i++; if (node < 0) return node; memset(dt, 0, sizeof(*dt)); ret |= decode_timing_property(blob, node, "hback-porch", &dt->hback_porch); ret |= decode_timing_property(blob, node, "hfront-porch", &dt->hfront_porch); ret |= decode_timing_property(blob, node, "hactive", &dt->hactive); ret |= decode_timing_property(blob, node, "hsync-len", &dt->hsync_len); ret |= decode_timing_property(blob, node, "vback-porch", &dt->vback_porch); ret |= decode_timing_property(blob, node, "vfront-porch", &dt->vfront_porch); ret |= decode_timing_property(blob, node, "vactive", &dt->vactive); ret |= decode_timing_property(blob, node, "vsync-len", &dt->vsync_len); ret |= decode_timing_property(blob, node, "clock-frequency", &dt->pixelclock); dt->flags = 0; val = fdtdec_get_int(blob, node, "vsync-active", -1); if (val != -1) { dt->flags |= val ? DISPLAY_FLAGS_VSYNC_HIGH : DISPLAY_FLAGS_VSYNC_LOW; } val = fdtdec_get_int(blob, node, "hsync-active", -1); if (val != -1) { dt->flags |= val ? DISPLAY_FLAGS_HSYNC_HIGH : DISPLAY_FLAGS_HSYNC_LOW; } val = fdtdec_get_int(blob, node, "de-active", -1); if (val != -1) { dt->flags |= val ? DISPLAY_FLAGS_DE_HIGH : DISPLAY_FLAGS_DE_LOW; } val = fdtdec_get_int(blob, node, "pixelclk-active", -1); if (val != -1) { dt->flags |= val ? DISPLAY_FLAGS_PIXDATA_POSEDGE : DISPLAY_FLAGS_PIXDATA_NEGEDGE; } if (fdtdec_get_bool(blob, node, "interlaced")) dt->flags |= DISPLAY_FLAGS_INTERLACED; if (fdtdec_get_bool(blob, node, "doublescan")) dt->flags |= DISPLAY_FLAGS_DOUBLESCAN; if (fdtdec_get_bool(blob, node, "doubleclk")) dt->flags |= DISPLAY_FLAGS_DOUBLECLK; return 0; }
/** * Get the host address and peripheral ID for a node. * * @param blob fdt blob * @param node Device index (0-3) * @param host Structure to fill in (reg, width, mmc_id) */ static int mmc_get_config(const void *blob, int node, struct mmc_host *host, bool *removablep) { debug("%s: node = %d\n", __func__, node); host->enabled = fdtdec_get_is_enabled(blob, node); host->reg = (struct tegra_mmc *)fdtdec_get_addr(blob, node, "reg"); if ((fdt_addr_t)host->reg == FDT_ADDR_T_NONE) { debug("%s: no sdmmc base reg info found\n", __func__); return -FDT_ERR_NOTFOUND; } #ifdef CONFIG_TEGRA186 { /* * FIXME: This variable should go away when the MMC device * actually is a udevice. */ struct udevice dev; int ret; dev.of_offset = node; ret = reset_get_by_name(&dev, "sdhci", &host->reset_ctl); if (ret) { debug("reset_get_by_name() failed: %d\n", ret); return ret; } ret = clk_get_by_index(&dev, 0, &host->clk); if (ret) { debug("clk_get_by_index() failed: %d\n", ret); return ret; } } #else host->mmc_id = clock_decode_periph_id(blob, node); if (host->mmc_id == PERIPH_ID_NONE) { debug("%s: could not decode periph id\n", __func__); return -FDT_ERR_NOTFOUND; } #endif /* * NOTE: mmc->bus_width is determined by mmc.c dynamically. * TBD: Override it with this value? */ host->width = fdtdec_get_int(blob, node, "bus-width", 0); if (!host->width) debug("%s: no sdmmc width found\n", __func__); /* These GPIOs are optional */ gpio_request_by_name_nodev(blob, node, "cd-gpios", 0, &host->cd_gpio, GPIOD_IS_IN); gpio_request_by_name_nodev(blob, node, "wp-gpios", 0, &host->wp_gpio, GPIOD_IS_IN); gpio_request_by_name_nodev(blob, node, "power-gpios", 0, &host->pwr_gpio, GPIOD_IS_OUT); *removablep = !fdtdec_get_bool(blob, node, "non-removable"); debug("%s: found controller at %p, width = %d, periph_id = %d\n", __func__, host->reg, host->width, #ifndef CONFIG_TEGRA186 host->mmc_id #else -1 #endif ); return 0; }
static int omap_hsmmc_set_ios(struct mmc *mmc) { struct omap_hsmmc_data *priv = omap_hsmmc_get_data(mmc); #else static int omap_hsmmc_set_ios(struct udevice *dev) { struct omap_hsmmc_data *priv = dev_get_priv(dev); struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); struct mmc *mmc = upriv->mmc; #endif struct hsmmc *mmc_base; unsigned int dsor = 0; ulong start; mmc_base = priv->base_addr; /* configue bus width */ switch (mmc->bus_width) { case 8: writel(readl(&mmc_base->con) | DTW_8_BITMODE, &mmc_base->con); break; case 4: writel(readl(&mmc_base->con) & ~DTW_8_BITMODE, &mmc_base->con); writel(readl(&mmc_base->hctl) | DTW_4_BITMODE, &mmc_base->hctl); break; case 1: default: writel(readl(&mmc_base->con) & ~DTW_8_BITMODE, &mmc_base->con); writel(readl(&mmc_base->hctl) & ~DTW_4_BITMODE, &mmc_base->hctl); break; } /* configure clock with 96Mhz system clock. */ if (mmc->clock != 0) { dsor = (MMC_CLOCK_REFERENCE * 1000000 / mmc->clock); if ((MMC_CLOCK_REFERENCE * 1000000) / dsor > mmc->clock) dsor++; } mmc_reg_out(&mmc_base->sysctl, (ICE_MASK | DTO_MASK | CEN_MASK), (ICE_STOP | DTO_15THDTO | CEN_DISABLE)); mmc_reg_out(&mmc_base->sysctl, ICE_MASK | CLKD_MASK, (dsor << CLKD_OFFSET) | ICE_OSCILLATE); start = get_timer(0); while ((readl(&mmc_base->sysctl) & ICS_MASK) == ICS_NOTREADY) { if (get_timer(0) - start > MAX_RETRY_MS) { printf("%s: timedout waiting for ics!\n", __func__); return -ETIMEDOUT; } } writel(readl(&mmc_base->sysctl) | CEN_ENABLE, &mmc_base->sysctl); return 0; } #ifdef OMAP_HSMMC_USE_GPIO #if CONFIG_IS_ENABLED(DM_MMC) static int omap_hsmmc_getcd(struct udevice *dev) { struct omap_hsmmc_data *priv = dev_get_priv(dev); int value; value = dm_gpio_get_value(&priv->cd_gpio); /* if no CD return as 1 */ if (value < 0) return 1; if (priv->cd_inverted) return !value; return value; } static int omap_hsmmc_getwp(struct udevice *dev) { struct omap_hsmmc_data *priv = dev_get_priv(dev); int value; value = dm_gpio_get_value(&priv->wp_gpio); /* if no WP return as 0 */ if (value < 0) return 0; return value; } #else static int omap_hsmmc_getcd(struct mmc *mmc) { struct omap_hsmmc_data *priv = omap_hsmmc_get_data(mmc); int cd_gpio; /* if no CD return as 1 */ cd_gpio = priv->cd_gpio; if (cd_gpio < 0) return 1; /* NOTE: assumes card detect signal is active-low */ return !gpio_get_value(cd_gpio); } static int omap_hsmmc_getwp(struct mmc *mmc) { struct omap_hsmmc_data *priv = omap_hsmmc_get_data(mmc); int wp_gpio; /* if no WP return as 0 */ wp_gpio = priv->wp_gpio; if (wp_gpio < 0) return 0; /* NOTE: assumes write protect signal is active-high */ return gpio_get_value(wp_gpio); } #endif #endif #if CONFIG_IS_ENABLED(DM_MMC) static const struct dm_mmc_ops omap_hsmmc_ops = { .send_cmd = omap_hsmmc_send_cmd, .set_ios = omap_hsmmc_set_ios, #ifdef OMAP_HSMMC_USE_GPIO .get_cd = omap_hsmmc_getcd, .get_wp = omap_hsmmc_getwp, #endif }; #else static const struct mmc_ops omap_hsmmc_ops = { .send_cmd = omap_hsmmc_send_cmd, .set_ios = omap_hsmmc_set_ios, .init = omap_hsmmc_init_setup, #ifdef OMAP_HSMMC_USE_GPIO .getcd = omap_hsmmc_getcd, .getwp = omap_hsmmc_getwp, #endif }; #endif #if !CONFIG_IS_ENABLED(DM_MMC) int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max, int cd_gpio, int wp_gpio) { struct mmc *mmc; struct omap_hsmmc_data *priv; struct mmc_config *cfg; uint host_caps_val; priv = malloc(sizeof(*priv)); if (priv == NULL) return -1; host_caps_val = MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS; switch (dev_index) { case 0: priv->base_addr = (struct hsmmc *)OMAP_HSMMC1_BASE; break; #ifdef OMAP_HSMMC2_BASE case 1: priv->base_addr = (struct hsmmc *)OMAP_HSMMC2_BASE; #if (defined(CONFIG_OMAP44XX) || defined(CONFIG_OMAP54XX) || \ defined(CONFIG_DRA7XX) || defined(CONFIG_AM33XX) || \ defined(CONFIG_AM43XX) || defined(CONFIG_SOC_KEYSTONE)) && \ defined(CONFIG_HSMMC2_8BIT) /* Enable 8-bit interface for eMMC on OMAP4/5 or DRA7XX */ host_caps_val |= MMC_MODE_8BIT; #endif break; #endif #ifdef OMAP_HSMMC3_BASE case 2: priv->base_addr = (struct hsmmc *)OMAP_HSMMC3_BASE; #if defined(CONFIG_DRA7XX) && defined(CONFIG_HSMMC3_8BIT) /* Enable 8-bit interface for eMMC on DRA7XX */ host_caps_val |= MMC_MODE_8BIT; #endif break; #endif default: priv->base_addr = (struct hsmmc *)OMAP_HSMMC1_BASE; return 1; } #ifdef OMAP_HSMMC_USE_GPIO /* on error gpio values are set to -1, which is what we want */ priv->cd_gpio = omap_mmc_setup_gpio_in(cd_gpio, "mmc_cd"); priv->wp_gpio = omap_mmc_setup_gpio_in(wp_gpio, "mmc_wp"); #endif cfg = &priv->cfg; cfg->name = "OMAP SD/MMC"; cfg->ops = &omap_hsmmc_ops; cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195; cfg->host_caps = host_caps_val & ~host_caps_mask; cfg->f_min = 400000; if (f_max != 0) cfg->f_max = f_max; else { if (cfg->host_caps & MMC_MODE_HS) { if (cfg->host_caps & MMC_MODE_HS_52MHz) cfg->f_max = 52000000; else cfg->f_max = 26000000; } else cfg->f_max = 20000000; } cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; #if defined(CONFIG_OMAP34XX) /* * Silicon revs 2.1 and older do not support multiblock transfers. */ if ((get_cpu_family() == CPU_OMAP34XX) && (get_cpu_rev() <= CPU_3XX_ES21)) cfg->b_max = 1; #endif mmc = mmc_create(cfg, priv); if (mmc == NULL) return -1; return 0; } #else #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA) static int omap_hsmmc_ofdata_to_platdata(struct udevice *dev) { struct omap_hsmmc_plat *plat = dev_get_platdata(dev); struct mmc_config *cfg = &plat->cfg; struct omap2_mmc_platform_config *data = (struct omap2_mmc_platform_config *)dev_get_driver_data(dev); const void *fdt = gd->fdt_blob; int node = dev_of_offset(dev); int val; plat->base_addr = map_physmem(devfdt_get_addr(dev), sizeof(struct hsmmc *), MAP_NOCACHE) + data->reg_offset; cfg->host_caps = MMC_MODE_HS_52MHz | MMC_MODE_HS; val = fdtdec_get_int(fdt, node, "bus-width", -1); if (val < 0) { printf("error: bus-width property missing\n"); return -ENOENT; } switch (val) { case 0x8: cfg->host_caps |= MMC_MODE_8BIT; case 0x4: cfg->host_caps |= MMC_MODE_4BIT; break; default: printf("error: invalid bus-width property\n"); return -ENOENT; } cfg->f_min = 400000; cfg->f_max = fdtdec_get_int(fdt, node, "max-frequency", 52000000); cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195; cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; #ifdef OMAP_HSMMC_USE_GPIO plat->cd_inverted = fdtdec_get_bool(fdt, node, "cd-inverted"); #endif return 0; } #endif #ifdef CONFIG_BLK static int omap_hsmmc_bind(struct udevice *dev) { struct omap_hsmmc_plat *plat = dev_get_platdata(dev); return mmc_bind(dev, &plat->mmc, &plat->cfg); } #endif static int omap_hsmmc_probe(struct udevice *dev) { struct omap_hsmmc_plat *plat = dev_get_platdata(dev); struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); struct omap_hsmmc_data *priv = dev_get_priv(dev); struct mmc_config *cfg = &plat->cfg; struct mmc *mmc; cfg->name = "OMAP SD/MMC"; priv->base_addr = plat->base_addr; #ifdef OMAP_HSMMC_USE_GPIO priv->cd_inverted = plat->cd_inverted; #endif #ifdef CONFIG_BLK mmc = &plat->mmc; #else mmc = mmc_create(cfg, priv); if (mmc == NULL) return -1; #endif #if defined(OMAP_HSMMC_USE_GPIO) && CONFIG_IS_ENABLED(OF_CONTROL) gpio_request_by_name(dev, "cd-gpios", 0, &priv->cd_gpio, GPIOD_IS_IN); gpio_request_by_name(dev, "wp-gpios", 0, &priv->wp_gpio, GPIOD_IS_IN); #endif mmc->dev = dev; upriv->mmc = mmc; return omap_hsmmc_init_setup(mmc); } #if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA) static const struct omap2_mmc_platform_config omap3_mmc_pdata = { .reg_offset = 0, }; static const struct omap2_mmc_platform_config am33xx_mmc_pdata = { .reg_offset = 0x100, }; static const struct omap2_mmc_platform_config omap4_mmc_pdata = { .reg_offset = 0x100, }; static const struct udevice_id omap_hsmmc_ids[] = { { .compatible = "ti,omap3-hsmmc", .data = (ulong)&omap3_mmc_pdata }, { .compatible = "ti,omap4-hsmmc", .data = (ulong)&omap4_mmc_pdata }, { .compatible = "ti,am33xx-hsmmc", .data = (ulong)&am33xx_mmc_pdata }, { } };
/* i8042_kbd_init - reset keyboard and init state flags */ static int i8042_start(struct udevice *dev) { struct keyboard_priv *uc_priv = dev_get_uclass_priv(dev); struct i8042_kbd_priv *priv = dev_get_priv(dev); struct input_config *input = &uc_priv->input; int keymap, try; char *penv; int ret; if (!kbd_controller_present() || board_i8042_skip()) { debug("i8042 keyboard controller is not present\n"); return -ENOENT; } /* Init keyboard device (default US layout) */ keymap = KBD_US; penv = env_get("keymap"); if (penv != NULL) { if (strncmp(penv, "de", 3) == 0) keymap = KBD_GER; } for (try = 0; kbd_reset(priv->quirks) != 0; try++) { if (try >= KBD_RESET_TRIES) return -1; } ret = input_add_tables(input, keymap == KBD_GER); if (ret) return ret; i8042_kbd_update_leds(dev, NORMAL); debug("%s: started\n", __func__); return 0; } /** * Set up the i8042 keyboard. This is called by the stdio device handler * * We want to do this init when the keyboard is actually used rather than * at start-up, since keyboard input may not currently be selected. * * Once the keyboard starts there will be a period during which we must * wait for the keyboard to init. We do this only when a key is first * read - see kbd_wait_for_fifo_init(). * * @return 0 if ok, -ve on error */ static int i8042_kbd_probe(struct udevice *dev) { struct keyboard_priv *uc_priv = dev_get_uclass_priv(dev); struct i8042_kbd_priv *priv = dev_get_priv(dev); struct stdio_dev *sdev = &uc_priv->sdev; struct input_config *input = &uc_priv->input; int ret; if (fdtdec_get_bool(gd->fdt_blob, dev_of_offset(dev), "intel,duplicate-por")) priv->quirks |= QUIRK_DUP_POR; /* Register the device. i8042_start() will be called soon */ input->dev = dev; input->read_keys = i8042_kbd_check; input_allow_repeats(input, true); strcpy(sdev->name, "i8042-kbd"); ret = input_stdio_register(sdev); if (ret) { debug("%s: input_stdio_register() failed\n", __func__); return ret; } debug("%s: ready\n", __func__); return 0; } static const struct keyboard_ops i8042_kbd_ops = { .start = i8042_start, .update_leds = i8042_kbd_update_leds, }; static const struct udevice_id i8042_kbd_ids[] = { { .compatible = "intel,i8042-keyboard" }, { } };