X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=drivers%2Fmmc%2Fomap_hsmmc.c;h=be34057ea2cef9108cd842c7237fc70726d853a8;hb=e98dd20ccec30311dddd165f945c7ce0dedef6db;hp=8238a7e8e0087852cc05d882b5d32b60400efec0;hpb=d81572c272d4b0980fb9b8a02e1357090b002398;p=u-boot diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c index 8238a7e8e0..be34057ea2 100644 --- a/drivers/mmc/omap_hsmmc.c +++ b/drivers/mmc/omap_hsmmc.c @@ -31,10 +31,15 @@ #include #include #include -#include #include #include +#if !defined(CONFIG_SOC_KEYSTONE) +#include #include +#endif +#include + +DECLARE_GLOBAL_DATA_PTR; /* simplify defines to OMAP_HSMMC_USE_GPIO */ #if (defined(CONFIG_OMAP_GPIO) && !defined(CONFIG_SPL_BUILD)) || \ @@ -52,9 +57,15 @@ struct omap_hsmmc_data { struct hsmmc *base_addr; struct mmc_config cfg; #ifdef OMAP_HSMMC_USE_GPIO +#ifdef CONFIG_DM_MMC + struct gpio_desc cd_gpio; /* Change Detect GPIO */ + struct gpio_desc wp_gpio; /* Write Protect GPIO */ + bool cd_inverted; +#else int cd_gpio; int wp_gpio; #endif +#endif }; /* If we fail after 1 second wait, something is really bad */ @@ -64,7 +75,7 @@ static int mmc_read_data(struct hsmmc *mmc_base, char *buf, unsigned int size); static int mmc_write_data(struct hsmmc *mmc_base, const char *buf, unsigned int siz); -#ifdef OMAP_HSMMC_USE_GPIO +#if defined(OMAP_HSMMC_USE_GPIO) && !defined(CONFIG_DM_MMC) static int omap_mmc_setup_gpio_in(int gpio, const char *label) { int ret; @@ -85,7 +96,7 @@ static int omap_mmc_setup_gpio_in(int gpio, const char *label) } #endif -#if defined(CONFIG_OMAP44XX) && defined(CONFIG_TWL6030_POWER) +#if defined(CONFIG_OMAP44XX) static void omap4_vmmc_pbias_config(struct mmc *mmc) { u32 value = 0; @@ -93,8 +104,6 @@ static void omap4_vmmc_pbias_config(struct mmc *mmc) value = readl((*ctrl)->control_pbiaslite); value &= ~(MMC1_PBIASLITE_PWRDNZ | MMC1_PWRDNZ); writel(value, (*ctrl)->control_pbiaslite); - /* set VMMC to 3V */ - twl6030_power_mmc_init(); value = readl((*ctrl)->control_pbiaslite); value |= MMC1_PBIASLITE_VMODE | MMC1_PBIASLITE_PWRDNZ | MMC1_PWRDNZ; writel(value, (*ctrl)->control_pbiaslite); @@ -164,13 +173,13 @@ static unsigned char mmc_board_init(struct mmc *mmc) &prcm_base->iclken1_core); #endif -#if defined(CONFIG_OMAP44XX) && defined(CONFIG_TWL6030_POWER) +#if defined(CONFIG_OMAP44XX) /* PBIAS config needed for MMC1 only */ - if (mmc->block_dev.dev == 0) + if (mmc->block_dev.devnum == 0) omap4_vmmc_pbias_config(mmc); #endif #if defined(CONFIG_OMAP54XX) && defined(CONFIG_PALMAS_POWER) - if (mmc->block_dev.dev == 0) + if (mmc->block_dev.devnum == 0) omap5_pbias_config(mmc); #endif @@ -296,7 +305,7 @@ static void mmc_reset_controller_fsm(struct hsmmc *mmc_base, u32 bit) * (reset procedure is completed). */ #if defined(CONFIG_OMAP44XX) || defined(CONFIG_OMAP54XX) || \ - defined(CONFIG_AM33XX) + defined(CONFIG_AM33XX) || defined(CONFIG_AM43XX) if (!(readl(&mmc_base->sysctl) & bit)) { start = get_timer(0); while (!(readl(&mmc_base->sysctl) & bit)) { @@ -600,6 +609,34 @@ static void omap_hsmmc_set_ios(struct mmc *mmc) } #ifdef OMAP_HSMMC_USE_GPIO +#ifdef CONFIG_DM_MMC +static int omap_hsmmc_getcd(struct mmc *mmc) +{ + struct omap_hsmmc_data *priv = mmc->priv; + 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 mmc *mmc) +{ + struct omap_hsmmc_data *priv = mmc->priv; + 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_data = mmc->priv; @@ -628,6 +665,7 @@ static int omap_hsmmc_getwp(struct mmc *mmc) return gpio_get_value(wp_gpio); } #endif +#endif static const struct mmc_ops omap_hsmmc_ops = { .send_cmd = omap_hsmmc_send_cmd, @@ -639,6 +677,7 @@ static const struct mmc_ops omap_hsmmc_ops = { #endif }; +#ifndef CONFIG_DM_MMC int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max, int cd_gpio, int wp_gpio) { @@ -661,7 +700,8 @@ int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max, int cd_gpio, case 1: priv_data->base_addr = (struct hsmmc *)OMAP_HSMMC2_BASE; #if (defined(CONFIG_OMAP44XX) || defined(CONFIG_OMAP54XX) || \ - defined(CONFIG_DRA7XX) || defined(CONFIG_AM57XX)) && \ + defined(CONFIG_DRA7XX) || defined(CONFIG_AM57XX) || \ + 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; @@ -724,3 +764,86 @@ int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max, int cd_gpio, return 0; } +#else +static int omap_hsmmc_ofdata_to_platdata(struct udevice *dev) +{ + struct omap_hsmmc_data *priv = dev_get_priv(dev); + const void *fdt = gd->fdt_blob; + int node = dev->of_offset; + struct mmc_config *cfg; + int val; + + priv->base_addr = map_physmem(dev_get_addr(dev), sizeof(struct hsmmc *), + MAP_NOCACHE); + cfg = &priv->cfg; + + 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; + + priv->cd_inverted = fdtdec_get_bool(fdt, node, "cd-inverted"); + + return 0; +} + +static int omap_hsmmc_probe(struct udevice *dev) +{ + struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); + struct omap_hsmmc_data *priv = dev_get_priv(dev); + struct mmc_config *cfg; + struct mmc *mmc; + + cfg = &priv->cfg; + cfg->name = "OMAP SD/MMC"; + cfg->ops = &omap_hsmmc_ops; + + mmc = mmc_create(cfg, priv); + if (mmc == NULL) + return -1; + +#ifdef OMAP_HSMMC_USE_GPIO + 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 0; +} + +static const struct udevice_id omap_hsmmc_ids[] = { + { .compatible = "ti,omap3-hsmmc" }, + { .compatible = "ti,omap4-hsmmc" }, + { .compatible = "ti,am33xx-hsmmc" }, + { } +}; + +U_BOOT_DRIVER(omap_hsmmc) = { + .name = "omap_hsmmc", + .id = UCLASS_MMC, + .of_match = omap_hsmmc_ids, + .ofdata_to_platdata = omap_hsmmc_ofdata_to_platdata, + .probe = omap_hsmmc_probe, + .priv_auto_alloc_size = sizeof(struct omap_hsmmc_data), +}; +#endif