From b706b1c24d98320fce12a402bd6960f407063d78 Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 20 Feb 2017 14:24:13 +0300 Subject: [PATCH 1/5] mmc: pci: Add CONFIG_MMC_PCI We don't want pci_mmc to compile every time x86 compiles, only when there's a platform that needs it. For that reason, we're adding a new CONFIG_MMC_PCI which platforms can choose to enable. Suggested-by: Jaehoon Chung Reviewed-by: Bin Meng Signed-off-by: Felipe Balbi Signed-off-by: Andy Shevchenko --- configs/bayleybay_defconfig | 1 + configs/conga-qeval20-qa3-e3845-internal-uart_defconfig | 1 + configs/conga-qeval20-qa3-e3845_defconfig | 1 + configs/crownbay_defconfig | 1 + configs/dfi-bt700-q7x-151_defconfig | 1 + configs/galileo_defconfig | 1 + configs/minnowmax_defconfig | 1 + configs/theadorable-x86-dfi-bt700_defconfig | 1 + drivers/mmc/Kconfig | 8 ++++++++ drivers/mmc/Makefile | 2 +- 10 files changed, 17 insertions(+), 1 deletion(-) diff --git a/configs/bayleybay_defconfig b/configs/bayleybay_defconfig index c6aa24f9be..d2f9f24a19 100644 --- a/configs/bayleybay_defconfig +++ b/configs/bayleybay_defconfig @@ -48,6 +48,7 @@ CONFIG_REGMAP=y CONFIG_SYSCON=y CONFIG_CPU=y CONFIG_MMC=y +CONFIG_MMC_PCI=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_SDMA=y CONFIG_SPI_FLASH=y diff --git a/configs/conga-qeval20-qa3-e3845-internal-uart_defconfig b/configs/conga-qeval20-qa3-e3845-internal-uart_defconfig index 890d28ce69..d96bfcbe14 100644 --- a/configs/conga-qeval20-qa3-e3845-internal-uart_defconfig +++ b/configs/conga-qeval20-qa3-e3845-internal-uart_defconfig @@ -50,6 +50,7 @@ CONFIG_DM_I2C=y CONFIG_SYS_I2C_INTEL=y CONFIG_WINBOND_W83627=y CONFIG_MMC=y +CONFIG_MMC_PCI=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_SDMA=y CONFIG_SPI_FLASH=y diff --git a/configs/conga-qeval20-qa3-e3845_defconfig b/configs/conga-qeval20-qa3-e3845_defconfig index 6e4cd843d9..1642bf2926 100644 --- a/configs/conga-qeval20-qa3-e3845_defconfig +++ b/configs/conga-qeval20-qa3-e3845_defconfig @@ -49,6 +49,7 @@ CONFIG_DM_I2C=y CONFIG_SYS_I2C_INTEL=y CONFIG_WINBOND_W83627=y CONFIG_MMC=y +CONFIG_MMC_PCI=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_SDMA=y CONFIG_SPI_FLASH=y diff --git a/configs/crownbay_defconfig b/configs/crownbay_defconfig index 13a00c2a17..4a88f5f3c5 100644 --- a/configs/crownbay_defconfig +++ b/configs/crownbay_defconfig @@ -37,6 +37,7 @@ CONFIG_REGMAP=y CONFIG_SYSCON=y CONFIG_CPU=y CONFIG_MMC=y +CONFIG_MMC_PCI=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_SDMA=y CONFIG_SPI_FLASH=y diff --git a/configs/dfi-bt700-q7x-151_defconfig b/configs/dfi-bt700-q7x-151_defconfig index ce447f540a..d5bd66f83c 100644 --- a/configs/dfi-bt700-q7x-151_defconfig +++ b/configs/dfi-bt700-q7x-151_defconfig @@ -47,6 +47,7 @@ CONFIG_CPU=y CONFIG_DM_I2C=y CONFIG_NUVOTON_NCT6102D=y CONFIG_MMC=y +CONFIG_MMC_PCI=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_SDMA=y CONFIG_SPI_FLASH=y diff --git a/configs/galileo_defconfig b/configs/galileo_defconfig index 570f9ea810..f60abc3422 100644 --- a/configs/galileo_defconfig +++ b/configs/galileo_defconfig @@ -42,6 +42,7 @@ CONFIG_REGMAP=y CONFIG_SYSCON=y CONFIG_CPU=y CONFIG_MMC=y +CONFIG_MMC_PCI=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_SDMA=y CONFIG_SPI_FLASH=y diff --git a/configs/minnowmax_defconfig b/configs/minnowmax_defconfig index 5f61f2a19c..8dac1d72fb 100644 --- a/configs/minnowmax_defconfig +++ b/configs/minnowmax_defconfig @@ -47,6 +47,7 @@ CONFIG_REGMAP=y CONFIG_SYSCON=y CONFIG_CPU=y CONFIG_MMC=y +CONFIG_MMC_PCI=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_SDMA=y CONFIG_SPI_FLASH=y diff --git a/configs/theadorable-x86-dfi-bt700_defconfig b/configs/theadorable-x86-dfi-bt700_defconfig index cde33bbfe1..1703cee841 100644 --- a/configs/theadorable-x86-dfi-bt700_defconfig +++ b/configs/theadorable-x86-dfi-bt700_defconfig @@ -47,6 +47,7 @@ CONFIG_CPU=y CONFIG_DM_I2C=y CONFIG_NUVOTON_NCT6102D=y CONFIG_MMC=y +CONFIG_MMC_PCI=y CONFIG_MMC_SDHCI=y CONFIG_MMC_SDHCI_SDMA=y CONFIG_SPI_FLASH=y diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index ddef59a3c0..78091cc217 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig @@ -122,6 +122,14 @@ config MMC_MXS If unsure, say N. +config MMC_PCI + bool "Support for MMC controllers on PCI" + help + This selects PCI-based MMC controllers. + If you have an MMC controller on a PCI bus, say Y here. + + If unsure, say N. + config MMC_OMAP_HS bool "TI OMAP High Speed Multimedia Card Interface support" help diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile index 6a488f1db9..1e8d23f012 100644 --- a/drivers/mmc/Makefile +++ b/drivers/mmc/Makefile @@ -34,7 +34,7 @@ obj-$(CONFIG_MVEBU_MMC) += mvebu_mmc.o obj-$(CONFIG_MMC_OMAP_HS) += omap_hsmmc.o obj-$(CONFIG_MMC_MXC) += mxcmmc.o obj-$(CONFIG_MMC_MXS) += mxsmmc.o -obj-$(CONFIG_X86) += pci_mmc.o +obj-$(CONFIG_MMC_PCI) += pci_mmc.o obj-$(CONFIG_PXA_MMC_GENERIC) += pxa_mmc_gen.o obj-$(CONFIG_SUPPORT_EMMC_RPMB) += rpmb.o obj-$(CONFIG_S3C_SDI) += s3c_sdi.o From 83b3248e7ebb4f030b599a13a2559aa1ae31a02c Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Mon, 20 Feb 2017 14:24:14 +0300 Subject: [PATCH 2/5] 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 Signed-off-by: Felipe Balbi Signed-off-by: Andy Shevchenko Reviewed-by: Bin Meng --- drivers/mmc/Kconfig | 14 +++++++ drivers/mmc/Makefile | 1 + drivers/mmc/tangier_sdhci.c | 81 +++++++++++++++++++++++++++++++++++++ 3 files changed, 96 insertions(+) create mode 100644 drivers/mmc/tangier_sdhci.c diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index 78091cc217..05e0b10f34 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 1e8d23f012..6a26a52c28 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 0000000000..77b18e75f0 --- /dev/null +++ b/drivers/mmc/tangier_sdhci.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2017 Intel Corporation + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#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), +}; From fa7720b21ef48f2d0ebd22f609fea7ec2cfe6c16 Mon Sep 17 00:00:00 2001 From: Kevin Liu Date: Wed, 8 Mar 2017 15:16:44 +0800 Subject: [PATCH 3/5] mmc: sdhci: only flush cache for data command No need to flush cache for command without data. Signed-off-by: Kevin Liu --- drivers/mmc/sdhci.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index 93cefd89cd..c94d58db65 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -242,8 +242,10 @@ static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd, sdhci_writel(host, cmd->cmdarg, SDHCI_ARGUMENT); #ifdef CONFIG_MMC_SDHCI_SDMA - trans_bytes = ALIGN(trans_bytes, CONFIG_SYS_CACHELINE_SIZE); - flush_cache(start_addr, trans_bytes); + if (data != 0) { + trans_bytes = ALIGN(trans_bytes, CONFIG_SYS_CACHELINE_SIZE); + flush_cache(start_addr, trans_bytes); + } #endif sdhci_writew(host, SDHCI_MAKE_CMD(cmd->cmdidx, flags), SDHCI_COMMAND); start = get_timer(0); From 166c2b8fd91f9aa9e51505083d03784135609bf3 Mon Sep 17 00:00:00 2001 From: Xu Ziyuan Date: Sun, 12 Mar 2017 14:19:04 +0800 Subject: [PATCH 4/5] mmc: drop unnecessary send_status request It's redundant to send cmd13 after cmd9 whose response is not R1b. The card devices will not be busy w/ cmd9. Signed-off-by: Ziyuan Xu --- drivers/mmc/mmc.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 3648950cf5..72fc17716e 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -1111,7 +1111,6 @@ static int mmc_startup(struct mmc *mmc) struct mmc_cmd cmd; ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN); ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, MMC_MAX_BLOCK_LEN); - int timeout = 1000; bool has_parts = false; bool part_completed; struct blk_desc *bdesc; @@ -1167,9 +1166,6 @@ static int mmc_startup(struct mmc *mmc) err = mmc_send_cmd(mmc, &cmd, NULL); - /* Waiting for the ready status */ - mmc_send_status(mmc, timeout); - if (err) return err; From de0359c21e7993f7cf39156932fb73d171b2450a Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Mon, 20 Mar 2017 17:00:32 +0100 Subject: [PATCH 5/5] mmc: xenon_sdhci: Add missing host->max_clk to Xenon SDHCI driver The Xenon SDHCI driver just missed the integration of this patch: git ID 6d0e34bf mmc: sdhci: Distinguish between base clock and maximum peripheral frequency With this patch applied, the SDHCI subsystem complains now with this warning while probing: sdhci_setup_cfg: Hardware doesn't specify base clock frequency This patch fixes this issue, by providing the missing host->max_clk variable to the SDHCI subsystem. Signed-off-by: Stefan Roese Cc: Hu Ziji Cc: Victor Gu Cc: Konstantin Porotchkin Cc: Nadav Haklai Cc: Stefan Herbrechtsmeier Cc: Jaehoon Chung --- drivers/mmc/xenon_sdhci.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/mmc/xenon_sdhci.c b/drivers/mmc/xenon_sdhci.c index f678110239..2a0d8b46c6 100644 --- a/drivers/mmc/xenon_sdhci.c +++ b/drivers/mmc/xenon_sdhci.c @@ -422,7 +422,8 @@ static int xenon_sdhci_probe(struct udevice *dev) host->ops = &xenon_sdhci_ops; - ret = sdhci_setup_cfg(&plat->cfg, host, XENON_MMC_MAX_CLK, 0); + host->max_clk = XENON_MMC_MAX_CLK; + ret = sdhci_setup_cfg(&plat->cfg, host, 0, 0); if (ret) return ret;