diff options
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/Makefile | 22 | ||||
-rw-r--r-- | drivers/mmc/bcm2835_sdhci.c | 1 | ||||
-rw-r--r-- | drivers/mmc/omap_hsmmc.c | 19 | ||||
-rw-r--r-- | drivers/mmc/s5p_sdhci.c | 2 | ||||
-rw-r--r-- | drivers/mmc/sdhci.c | 6 | ||||
-rw-r--r-- | drivers/mmc/sunxi_mmc.c | 58 | ||||
-rw-r--r-- | drivers/mmc/tegra_mmc.c | 3 |
7 files changed, 79 insertions, 32 deletions
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile index 464cee16d1..461d7d8ec1 100644 --- a/drivers/mmc/Makefile +++ b/drivers/mmc/Makefile @@ -5,37 +5,39 @@ # SPDX-License-Identifier: GPL-2.0+ # +obj-$(CONFIG_ARM_PL180_MMCI) += arm_pl180_mmci.o +obj-$(CONFIG_BCM2835_SDHCI) += bcm2835_sdhci.o obj-$(CONFIG_BFIN_SDH) += bfin_sdh.o obj-$(CONFIG_DAVINCI_MMC) += davinci_mmc.o +obj-$(CONFIG_DWMMC) += dw_mmc.o +obj-$(CONFIG_EXYNOS_DWMMC) += exynos_dw_mmc.o obj-$(CONFIG_FSL_ESDHC) += fsl_esdhc.o obj-$(CONFIG_FTSDC010) += ftsdc010_mci.o obj-$(CONFIG_FTSDC021) += ftsdc021_sdhci.o obj-$(CONFIG_GENERIC_MMC) += mmc.o obj-$(CONFIG_GENERIC_ATMEL_MCI) += gen_atmel_mci.o +obj-$(CONFIG_KONA_SDHCI) += kona_sdhci.o obj-$(CONFIG_MMC_SPI) += mmc_spi.o -obj-$(CONFIG_ARM_PL180_MMCI) += arm_pl180_mmci.o +obj-$(CONFIG_MMC_SUNXI) += sunxi_mmc.o obj-$(CONFIG_MV_SDHCI) += mv_sdhci.o +obj-$(CONFIG_MVEBU_MMC) += mvebu_mmc.o obj-$(CONFIG_MXC_MMC) += mxcmmc.o obj-$(CONFIG_MXS_MMC) += mxsmmc.o obj-$(CONFIG_OMAP_HSMMC) += omap_hsmmc.o obj-$(CONFIG_PXA_MMC_GENERIC) += pxa_mmc_gen.o -obj-$(CONFIG_SDHCI) += sdhci.o -obj-$(CONFIG_BCM2835_SDHCI) += bcm2835_sdhci.o -obj-$(CONFIG_KONA_SDHCI) += kona_sdhci.o +obj-$(CONFIG_SUPPORT_EMMC_RPMB) += rpmb.o obj-$(CONFIG_S3C_SDI) += s3c_sdi.o obj-$(CONFIG_S5P_SDHCI) += s5p_sdhci.o +obj-$(CONFIG_SDHCI) += sdhci.o obj-$(CONFIG_SH_MMCIF) += sh_mmcif.o +obj-$(CONFIG_SOCFPGA_DWMMC) += socfpga_dw_mmc.o obj-$(CONFIG_SPEAR_SDHCI) += spear_sdhci.o obj-$(CONFIG_TEGRA_MMC) += tegra_mmc.o -obj-$(CONFIG_DWMMC) += dw_mmc.o -obj-$(CONFIG_EXYNOS_DWMMC) += exynos_dw_mmc.o -obj-$(CONFIG_MMC_SUNXI) += sunxi_mmc.o obj-$(CONFIG_ZYNQ_SDHCI) += zynq_sdhci.o -obj-$(CONFIG_SOCFPGA_DWMMC) += socfpga_dw_mmc.o -obj-$(CONFIG_SUPPORT_EMMC_RPMB) += rpmb.o + ifdef CONFIG_SPL_BUILD obj-$(CONFIG_SPL_MMC_BOOT) += fsl_esdhc_spl.o else obj-$(CONFIG_GENERIC_MMC) += mmc_write.o endif -obj-$(CONFIG_MVEBU_MMC) += mvebu_mmc.o + diff --git a/drivers/mmc/bcm2835_sdhci.c b/drivers/mmc/bcm2835_sdhci.c index 82079d67cd..92f7d8942f 100644 --- a/drivers/mmc/bcm2835_sdhci.c +++ b/drivers/mmc/bcm2835_sdhci.c @@ -40,6 +40,7 @@ #include <malloc.h> #include <sdhci.h> #include <asm/arch/timer.h> +#include <asm/arch-bcm2835/sdhci.h> /* 400KHz is max freq for card ID etc. Use that as min */ #define MIN_FREQ 400000 diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c index 5b0c302069..ffb5284a00 100644 --- a/drivers/mmc/omap_hsmmc.c +++ b/drivers/mmc/omap_hsmmc.c @@ -67,14 +67,19 @@ static int mmc_write_data(struct hsmmc *mmc_base, const char *buf, #ifdef OMAP_HSMMC_USE_GPIO static int omap_mmc_setup_gpio_in(int gpio, const char *label) { - if (!gpio_is_valid(gpio)) - return -1; + int ret; - if (gpio_request(gpio, label) < 0) +#ifndef CONFIG_DM_GPIO + if (!gpio_is_valid(gpio)) return -1; +#endif + ret = gpio_request(gpio, label); + if (ret) + return ret; - if (gpio_direction_input(gpio) < 0) - return -1; + ret = gpio_direction_input(gpio); + if (ret) + return ret; return gpio; } @@ -606,7 +611,8 @@ static int omap_hsmmc_getcd(struct mmc *mmc) if (cd_gpio < 0) return 1; - return gpio_get_value(cd_gpio); + /* NOTE: assumes card detect signal is active-low */ + return !gpio_get_value(cd_gpio); } static int omap_hsmmc_getwp(struct mmc *mmc) @@ -619,6 +625,7 @@ static int omap_hsmmc_getwp(struct mmc *mmc) if (wp_gpio < 0) return 0; + /* NOTE: assumes write protect signal is active-high */ return gpio_get_value(wp_gpio); } #endif diff --git a/drivers/mmc/s5p_sdhci.c b/drivers/mmc/s5p_sdhci.c index 0dea45d079..a5d34876bb 100644 --- a/drivers/mmc/s5p_sdhci.c +++ b/drivers/mmc/s5p_sdhci.c @@ -123,7 +123,7 @@ static int do_sdhci_init(struct sdhci_host *host) if (fdt_gpio_isvalid(&host->cd_gpio)) { sprintf(str, "sdhci%d_cd", host->index & 0xf); gpio_request(host->cd_gpio.gpio, str); - gpio_direction_output(host->cd_gpio.gpio, 1); + gpio_direction_input(host->cd_gpio.gpio); if (gpio_get_value(host->cd_gpio.gpio)) return -ENODEV; diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index 3125d13ba3..de88e19609 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -124,7 +124,7 @@ static int sdhci_transfer_data(struct sdhci_host *host, struct mmc_data *data, #endif #define CONFIG_SDHCI_CMD_DEFAULT_TIMEOUT 100 -int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd, +static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data) { struct sdhci_host *host = mmc->priv; @@ -355,7 +355,7 @@ static void sdhci_set_power(struct sdhci_host *host, unsigned short power) sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL); } -void sdhci_set_ios(struct mmc *mmc) +static void sdhci_set_ios(struct mmc *mmc) { u32 ctrl; struct sdhci_host *host = mmc->priv; @@ -393,7 +393,7 @@ void sdhci_set_ios(struct mmc *mmc) sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL); } -int sdhci_init(struct mmc *mmc) +static int sdhci_init(struct mmc *mmc) { struct sdhci_host *host = mmc->priv; diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c index d4e574fe19..231f0a0315 100644 --- a/drivers/mmc/sunxi_mmc.c +++ b/drivers/mmc/sunxi_mmc.c @@ -14,12 +14,13 @@ #include <asm/io.h> #include <asm/arch/clock.h> #include <asm/arch/cpu.h> +#include <asm/arch/gpio.h> #include <asm/arch/mmc.h> +#include <asm-generic/gpio.h> struct sunxi_mmc_host { unsigned mmc_no; uint32_t *mclkreg; - unsigned database; unsigned fatal_err; unsigned mod_clk; struct sunxi_mmc *reg; @@ -29,10 +30,22 @@ struct sunxi_mmc_host { /* support 4 mmc hosts */ struct sunxi_mmc_host mmc_host[4]; +static int sunxi_mmc_getcd_gpio(int sdc_no) +{ + switch (sdc_no) { + case 0: return sunxi_name_to_gpio(CONFIG_MMC0_CD_PIN); + case 1: return sunxi_name_to_gpio(CONFIG_MMC1_CD_PIN); + case 2: return sunxi_name_to_gpio(CONFIG_MMC2_CD_PIN); + case 3: return sunxi_name_to_gpio(CONFIG_MMC3_CD_PIN); + } + return -1; +} + static int mmc_resource_init(int sdc_no) { struct sunxi_mmc_host *mmchost = &mmc_host[sdc_no]; struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + int cd_pin, ret = 0; debug("init mmc %d resource\n", sdc_no); @@ -57,10 +70,13 @@ static int mmc_resource_init(int sdc_no) printf("Wrong mmc number %d\n", sdc_no); return -1; } - mmchost->database = (unsigned int)mmchost->reg + 0x100; mmchost->mmc_no = sdc_no; - return 0; + cd_pin = sunxi_mmc_getcd_gpio(sdc_no); + if (cd_pin != -1) + ret = gpio_request(cd_pin, "mmc_cd"); + + return ret; } static int mmc_clk_io_on(int sdc_no) @@ -75,6 +91,11 @@ static int mmc_clk_io_on(int sdc_no) /* config ahb clock */ setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_MMC(sdc_no)); +#if defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN8I) + /* unassert reset */ + setbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_RESET_OFFSET_MMC(sdc_no)); +#endif + /* config mod clock */ pll_clk = clock_get_pll6(); /* should be close to 100 MHz but no more, so round up */ @@ -194,9 +215,9 @@ static int mmc_trans_data_by_cpu(struct mmc *mmc, struct mmc_data *data) } if (reading) - buff[i] = readl(mmchost->database); + buff[i] = readl(&mmchost->reg->fifo); else - writel(buff[i], mmchost->database); + writel(buff[i], &mmchost->reg->fifo); } return 0; @@ -343,13 +364,26 @@ out: return error; } +static int sunxi_mmc_getcd(struct mmc *mmc) +{ + struct sunxi_mmc_host *mmchost = mmc->priv; + int cd_pin; + + cd_pin = sunxi_mmc_getcd_gpio(mmchost->mmc_no); + if (cd_pin == -1) + return 1; + + return !gpio_direction_input(cd_pin); +} + static const struct mmc_ops sunxi_mmc_ops = { .send_cmd = mmc_send_cmd, .set_ios = mmc_set_ios, .init = mmc_core_init, + .getcd = sunxi_mmc_getcd, }; -int sunxi_mmc_init(int sdc_no) +struct mmc *sunxi_mmc_init(int sdc_no) { struct mmc_config *cfg = &mmc_host[sdc_no].cfg; @@ -361,16 +395,18 @@ int sunxi_mmc_init(int sdc_no) cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34; cfg->host_caps = MMC_MODE_4BIT; cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS; +#if defined(CONFIG_MACH_SUN6I) || defined(CONFIG_MACH_SUN7I) || defined(CONFIG_MACH_SUN8I) + cfg->host_caps |= MMC_MODE_HC; +#endif cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; cfg->f_min = 400000; cfg->f_max = 52000000; - mmc_resource_init(sdc_no); - mmc_clk_io_on(sdc_no); + if (mmc_resource_init(sdc_no) != 0) + return NULL; - if (mmc_create(cfg, &mmc_host[sdc_no]) == NULL) - return -1; + mmc_clk_io_on(sdc_no); - return 0; + return mmc_create(cfg, &mmc_host[sdc_no]); } diff --git a/drivers/mmc/tegra_mmc.c b/drivers/mmc/tegra_mmc.c index 2642fe2065..2bd36b0ee7 100644 --- a/drivers/mmc/tegra_mmc.c +++ b/drivers/mmc/tegra_mmc.c @@ -13,6 +13,7 @@ #include <asm/io.h> #include <asm/arch/clock.h> #include <asm/arch-tegra/clk_rst.h> +#include <asm/arch-tegra/mmc.h> #include <asm/arch-tegra/tegra_mmc.h> #include <mmc.h> @@ -508,7 +509,7 @@ static int tegra_mmc_core_init(struct mmc *mmc) return 0; } -int tegra_mmc_getcd(struct mmc *mmc) +static int tegra_mmc_getcd(struct mmc *mmc) { struct mmc_host *host = mmc->priv; |