diff options
author | Felipe Balbi <felipe.balbi@linux.intel.com> | 2017-02-20 11:24:14 (GMT) |
---|---|---|
committer | Stefan Roese <sr@denx.de> | 2017-03-29 05:38:06 (GMT) |
commit | aff32df522e5b1a7e4391fd00ffe14a3f107fcd3 (patch) | |
tree | ffbb2f271fd89a3e150405fd5162a3a92e190090 /drivers | |
parent | ac9c4912c07e0aba1f8b1c993f2fc8051a34fea2 (diff) | |
download | u-boot-aff32df522e5b1a7e4391fd00ffe14a3f107fcd3.tar.xz |
mmc: tangier: Add Intel Tangier eMMC/SDHCI driver
This patch adds Intel Tangier eMMC/SDHCI driver.
Intel Tangier SoC contains a hybrid of PCI and non-PCI devices. SDHCI
controller is one of the devices which are *not* on a PCI and, hence,
cannot be enumerated by standard PCI means. This driver, allows for
SDHCI controller on Tangier SoC to work in U-Boot.
Signed-off-by: Vincent Tinelli <vincent.tinelli@intel.com>
Signed-off-by: Felipe Balbi <felipe.balbi@linux.intel.com>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mmc/Kconfig | 14 | ||||
-rw-r--r-- | drivers/mmc/Makefile | 1 | ||||
-rw-r--r-- | drivers/mmc/tangier_sdhci.c | 81 |
3 files changed, 96 insertions, 0 deletions
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index 78091cc..05e0b10 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig @@ -325,6 +325,20 @@ config MMC_SDHCI_XENON If unsure, say N. +config MMC_SDHCI_TANGIER + bool "Tangier SDHCI controller support" + depends on DM_MMC && BLK + depends on MMC_SDHCI + help + This selects support for SDHCI controller on Tanginer + SoC. Note that this controller does not sit on PCI bus and, + hence, cannot be enumerated by standard PCI means. + + If you're using an Intel Tangier SoC (available on Intel + Edison board), say Y here. + + If unsure, say N. + config MMC_SDHCI_TEGRA bool "SDHCI platform support for the Tegra SD/MMC Controller" depends on TEGRA diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile index 1e8d23f..6a26a52 100644 --- a/drivers/mmc/Makefile +++ b/drivers/mmc/Makefile @@ -62,6 +62,7 @@ obj-$(CONFIG_MMC_SDHCI_ROCKCHIP) += rockchip_sdhci.o obj-$(CONFIG_MMC_SDHCI_S5P) += s5p_sdhci.o obj-$(CONFIG_MMC_SDHCI_SPEAR) += spear_sdhci.o obj-$(CONFIG_MMC_SDHCI_STI) += sti_sdhci.o +obj-$(CONFIG_MMC_SDHCI_TANGIER) += tangier_sdhci.o obj-$(CONFIG_MMC_SDHCI_TEGRA) += tegra_mmc.o obj-$(CONFIG_MMC_SDHCI_XENON) += xenon_sdhci.o obj-$(CONFIG_MMC_SDHCI_ZYNQ) += zynq_sdhci.o diff --git a/drivers/mmc/tangier_sdhci.c b/drivers/mmc/tangier_sdhci.c new file mode 100644 index 0000000..77b18e7 --- /dev/null +++ b/drivers/mmc/tangier_sdhci.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2017 Intel Corporation + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include <common.h> +#include <dm.h> +#include <dm/device.h> +#include <linux/io.h> +#include <linux/sizes.h> +#include <malloc.h> +#include <mmc.h> +#include <sdhci.h> + +#define SDHCI_TANGIER_FMAX 200000000 +#define SDHCI_TANGIER_FMIN 400000 + +struct sdhci_tangier_plat { + struct mmc_config cfg; + struct mmc mmc; + void __iomem *ioaddr; +}; + +static int sdhci_tangier_bind(struct udevice *dev) +{ + struct sdhci_tangier_plat *plat = dev_get_platdata(dev); + + return sdhci_bind(dev, &plat->mmc, &plat->cfg); +} + +static int sdhci_tangier_probe(struct udevice *dev) +{ + struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); + struct sdhci_tangier_plat *plat = dev_get_platdata(dev); + struct sdhci_host *host = dev_get_priv(dev); + fdt_addr_t base; + int ret; + + base = dev_get_addr(dev); + if (base == FDT_ADDR_T_NONE) + return -EINVAL; + + plat->ioaddr = devm_ioremap(dev, base, SZ_1K); + if (!plat->ioaddr) + return -ENOMEM; + + host->name = dev->name; + host->ioaddr = plat->ioaddr; + host->quirks = SDHCI_QUIRK_NO_HISPD_BIT | SDHCI_QUIRK_BROKEN_VOLTAGE | + SDHCI_QUIRK_32BIT_DMA_ADDR | SDHCI_QUIRK_WAIT_SEND_CMD; + + /* MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195 */ + host->voltages = MMC_VDD_165_195; + + ret = sdhci_setup_cfg(&plat->cfg, host, SDHCI_TANGIER_FMAX, + SDHCI_TANGIER_FMIN); + if (ret) + return ret; + + upriv->mmc = &plat->mmc; + host->mmc = &plat->mmc; + host->mmc->priv = host; + + return sdhci_probe(dev); +} + +static const struct udevice_id sdhci_tangier_match[] = { + { .compatible = "intel,sdhci-tangier" }, + { /* sentinel */ } +}; + +U_BOOT_DRIVER(sdhci_tangier) = { + .name = "sdhci-tangier", + .id = UCLASS_MMC, + .of_match = sdhci_tangier_match, + .bind = sdhci_tangier_bind, + .probe = sdhci_tangier_probe, + .ops = &sdhci_ops, + .priv_auto_alloc_size = sizeof(struct sdhci_host), + .platdata_auto_alloc_size = sizeof(struct sdhci_tangier_plat), +}; |