diff options
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/Kconfig | 9 | ||||
-rw-r--r-- | drivers/mmc/davinci_mmc.c | 63 | ||||
-rw-r--r-- | drivers/mmc/mmc.c | 2 | ||||
-rw-r--r-- | drivers/mmc/omap_hsmmc.c | 3 | ||||
-rw-r--r-- | drivers/mmc/pxa_mmc_gen.c | 160 | ||||
-rw-r--r-- | drivers/mmc/zynq_sdhci.c | 2 |
6 files changed, 170 insertions, 69 deletions
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index 8f56572c39a..ad86c232c43 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig @@ -66,7 +66,6 @@ config MMC_SPI_CRC_ON config ARM_PL180_MMCI bool "ARM AMBA Multimedia Card Interface and compatible support" - depends on DM_MMC && OF_CONTROL help This selects the ARM(R) AMBA(R) PrimeCell Multimedia Card Interface (PL180, PL181 and compatible) support. @@ -300,6 +299,14 @@ config MMC_PCI If unsure, say N. +config PXA_MMC_GENERIC + bool "Support for MMC controllers on PXA" + help + This selects MMC controllers on PXA. + If you are on a PXA architecture, say Y here. + + If unsure, say N. + config MMC_OMAP_HS bool "TI OMAP High Speed Multimedia Card Interface support" select DM_REGULATOR_PBIAS if DM_MMC && DM_REGULATOR diff --git a/drivers/mmc/davinci_mmc.c b/drivers/mmc/davinci_mmc.c index 2408a687d23..4ef9f7cc8bc 100644 --- a/drivers/mmc/davinci_mmc.c +++ b/drivers/mmc/davinci_mmc.c @@ -18,7 +18,6 @@ #include <asm-generic/gpio.h> #include <linux/delay.h> -#define DAVINCI_MAX_BLOCKS (32) #define WATCHDOG_COUNT (100000) #define get_val(addr) REG(addr) @@ -34,12 +33,6 @@ struct davinci_mmc_priv { struct gpio_desc cd_gpio; /* Card Detect GPIO */ struct gpio_desc wp_gpio; /* Write Protect GPIO */ }; - -struct davinci_mmc_plat -{ - struct mmc_config cfg; - struct mmc mmc; -}; #endif /* Set davinci clock prescalar value based on the required clock in HZ */ @@ -487,43 +480,16 @@ static int davinci_mmc_probe(struct udevice *dev) struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); struct davinci_mmc_plat *plat = dev_get_platdata(dev); struct davinci_mmc_priv *priv = dev_get_priv(dev); - struct mmc_config *cfg = &plat->cfg; -#ifdef CONFIG_SPL_BUILD - int ret; -#endif - - cfg->f_min = 200000; - cfg->f_max = 25000000; - cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34, - cfg->host_caps = MMC_MODE_4BIT, /* DA850 supports only 4-bit SD/MMC */ - cfg->b_max = DAVINCI_MAX_BLOCKS; - cfg->name = "da830-mmc"; - priv->reg_base = (struct davinci_mmc_regs *)dev_read_addr(dev); + priv->reg_base = plat->reg_base; priv->input_clk = clk_get(DAVINCI_MMCSD_CLKID); - #if CONFIG_IS_ENABLED(DM_GPIO) /* These GPIOs are optional */ 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 - upriv->mmc = &plat->mmc; -#ifdef CONFIG_SPL_BUILD - /* - * FIXME This is a temporary workaround to enable the driver model in - * SPL on omapl138-lcdk. For some reason the bind() callback is not - * being called in SPL for MMC which breaks the mmc boot - the hack - * is to call mmc_bind() from probe(). We also don't have full DT - * support in SPL, hence the hard-coded base register address. - */ - priv->reg_base = (struct davinci_mmc_regs *)DAVINCI_MMC_SD0_BASE; - ret = mmc_bind(dev, &plat->mmc, &plat->cfg); - if (ret) - return ret; -#endif - return davinci_dm_mmc_init(dev); } @@ -534,21 +500,44 @@ static int davinci_mmc_bind(struct udevice *dev) return mmc_bind(dev, &plat->mmc, &plat->cfg); } +#if CONFIG_IS_ENABLED(OF_CONTROL) +static int davinci_mmc_ofdata_to_platdata(struct udevice *dev) +{ + struct davinci_mmc_plat *plat = dev_get_platdata(dev); + struct mmc_config *cfg = &plat->cfg; + + plat->reg_base = (struct davinci_mmc_regs *)dev_read_addr(dev); + cfg->f_min = 200000; + cfg->f_max = 25000000; + cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34, + cfg->host_caps = MMC_MODE_4BIT, /* DA850 supports only 4-bit SD/MMC */ + cfg->b_max = DAVINCI_MAX_BLOCKS; + cfg->name = "da830-mmc"; + + return 0; +} + static const struct udevice_id davinci_mmc_ids[] = { { .compatible = "ti,da830-mmc" }, {}, }; - +#endif U_BOOT_DRIVER(davinci_mmc_drv) = { .name = "davinci_mmc", .id = UCLASS_MMC, +#if CONFIG_IS_ENABLED(OF_CONTROL) .of_match = davinci_mmc_ids, + .platdata_auto_alloc_size = sizeof(struct davinci_mmc_plat), + .ofdata_to_platdata = davinci_mmc_ofdata_to_platdata, +#endif #if CONFIG_BLK .bind = davinci_mmc_bind, #endif .probe = davinci_mmc_probe, .ops = &davinci_mmc_ops, - .platdata_auto_alloc_size = sizeof(struct davinci_mmc_plat), .priv_auto_alloc_size = sizeof(struct davinci_mmc_priv), +#if !CONFIG_IS_ENABLED(OF_CONTROL) + .flags = DM_FLAG_PRE_RELOC, +#endif }; #endif diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 725a36799d3..50f47d4ba26 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -2831,7 +2831,7 @@ retry: if (err) return err; - /* The internal partition reset to user partition(0) at every CMD0*/ + /* The internal partition reset to user partition(0) at every CMD0 */ mmc_get_blk_desc(mmc)->hwpart = 0; /* Test for SD version 2 */ diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c index 8636cd713a3..0e05fe4cfcb 100644 --- a/drivers/mmc/omap_hsmmc.c +++ b/drivers/mmc/omap_hsmmc.c @@ -175,6 +175,8 @@ static inline struct omap_hsmmc_data *omap_hsmmc_get_data(struct mmc *mmc) return (struct omap_hsmmc_data *)mmc->priv; #endif } + +#if defined(CONFIG_OMAP34XX) || defined(CONFIG_IODELAY_RECALIBRATION) static inline struct mmc_config *omap_hsmmc_get_cfg(struct mmc *mmc) { #if CONFIG_IS_ENABLED(DM_MMC) @@ -184,6 +186,7 @@ static inline struct mmc_config *omap_hsmmc_get_cfg(struct mmc *mmc) return &((struct omap_hsmmc_data *)mmc->priv)->cfg; #endif } +#endif #if defined(OMAP_HSMMC_USE_GPIO) && !CONFIG_IS_ENABLED(DM_MMC) static int omap_mmc_setup_gpio_in(int gpio, const char *label) diff --git a/drivers/mmc/pxa_mmc_gen.c b/drivers/mmc/pxa_mmc_gen.c index cc6014703cc..2c081fdc69f 100644 --- a/drivers/mmc/pxa_mmc_gen.c +++ b/drivers/mmc/pxa_mmc_gen.c @@ -2,6 +2,9 @@ /* * Copyright (C) 2010 Marek Vasut <marek.vasut@gmail.com> * + * Modified to add driver model (DM) support + * Copyright (C) 2019 Marcel Ziswiler <marcel@ziswiler.com> + * * Loosely based on the old code and Linux's PXA MMC driver */ @@ -11,6 +14,8 @@ #include <linux/delay.h> #include <linux/errno.h> #include <asm/io.h> +#include <dm.h> +#include <dm/platform_data/pxa_mmc_gen.h> #include <malloc.h> #include <mmc.h> @@ -96,7 +101,7 @@ static int pxa_mmc_stop_clock(struct mmc *mmc) } static int pxa_mmc_start_cmd(struct mmc *mmc, struct mmc_cmd *cmd, - uint32_t cmdat) + uint32_t cmdat) { struct pxa_mmc_priv *priv = mmc->priv; struct pxa_mmc_regs *regs = priv->regs; @@ -143,7 +148,7 @@ static int pxa_mmc_cmd_done(struct mmc *mmc, struct mmc_cmd *cmd) { struct pxa_mmc_priv *priv = mmc->priv; struct pxa_mmc_regs *regs = priv->regs; - uint32_t a, b, c; + u32 a, b, c; int i; int stat; @@ -152,7 +157,7 @@ static int pxa_mmc_cmd_done(struct mmc *mmc, struct mmc_cmd *cmd) /* * Linux says: - * Did I mention this is Sick. We always need to + * Did I mention this is Sick. We always need to * discard the upper 8 bits of the first 16-bit word. */ a = readl(®s->res) & 0xffff; @@ -164,13 +169,13 @@ static int pxa_mmc_cmd_done(struct mmc *mmc, struct mmc_cmd *cmd) } /* The command response didn't arrive */ - if (stat & MMC_STAT_TIME_OUT_RESPONSE) + if (stat & MMC_STAT_TIME_OUT_RESPONSE) { return -ETIMEDOUT; - else if (stat & MMC_STAT_RES_CRC_ERROR - && cmd->resp_type & MMC_RSP_CRC) { -#ifdef PXAMMC_CRC_SKIP - if (cmd->resp_type & MMC_RSP_136 - && cmd->response[0] & (1 << 31)) + } else if (stat & MMC_STAT_RES_CRC_ERROR && + cmd->resp_type & MMC_RSP_CRC) { +#ifdef PXAMMC_CRC_SKIP + if (cmd->resp_type & MMC_RSP_136 && + cmd->response[0] & (1 << 31)) printf("Ignoring CRC, this may be dangerous!\n"); else #endif @@ -185,8 +190,8 @@ static int pxa_mmc_do_read_xfer(struct mmc *mmc, struct mmc_data *data) { struct pxa_mmc_priv *priv = mmc->priv; struct pxa_mmc_regs *regs = priv->regs; - uint32_t len; - uint32_t *buf = (uint32_t *)data->dest; + u32 len; + u32 *buf = (uint32_t *)data->dest; int size; int ret; @@ -202,7 +207,6 @@ static int pxa_mmc_do_read_xfer(struct mmc *mmc, struct mmc_data *data) /* Read data into the buffer */ while (size--) *buf++ = readl(®s->rxfifo); - } if (readl(®s->stat) & MMC_STAT_ERRORS) @@ -221,8 +225,8 @@ static int pxa_mmc_do_write_xfer(struct mmc *mmc, struct mmc_data *data) { struct pxa_mmc_priv *priv = mmc->priv; struct pxa_mmc_regs *regs = priv->regs; - uint32_t len; - uint32_t *buf = (uint32_t *)data->src; + u32 len; + u32 *buf = (uint32_t *)data->src; int size; int ret; @@ -259,12 +263,11 @@ static int pxa_mmc_do_write_xfer(struct mmc *mmc, struct mmc_data *data) return 0; } -static int pxa_mmc_request(struct mmc *mmc, struct mmc_cmd *cmd, - struct mmc_data *data) +static int pxa_mmc_send_cmd_common(struct pxa_mmc_priv *priv, struct mmc *mmc, + struct mmc_cmd *cmd, struct mmc_data *data) { - struct pxa_mmc_priv *priv = mmc->priv; struct pxa_mmc_regs *regs = priv->regs; - uint32_t cmdat = 0; + u32 cmdat = 0; int ret; /* Stop the controller */ @@ -313,12 +316,11 @@ static int pxa_mmc_request(struct mmc *mmc, struct mmc_cmd *cmd, return 0; } -static int pxa_mmc_set_ios(struct mmc *mmc) +static int pxa_mmc_set_ios_common(struct pxa_mmc_priv *priv, struct mmc *mmc) { - struct pxa_mmc_priv *priv = mmc->priv; struct pxa_mmc_regs *regs = priv->regs; - uint32_t tmp; - uint32_t pxa_mmc_clock; + u32 tmp; + u32 pxa_mmc_clock; if (!mmc->clock) { pxa_mmc_stop_clock(mmc); @@ -346,9 +348,8 @@ static int pxa_mmc_set_ios(struct mmc *mmc) return 0; } -static int pxa_mmc_init(struct mmc *mmc) +static int pxa_mmc_init_common(struct pxa_mmc_priv *priv, struct mmc *mmc) { - struct pxa_mmc_priv *priv = mmc->priv; struct pxa_mmc_regs *regs = priv->regs; /* Make sure the clock are stopped */ @@ -362,10 +363,34 @@ static int pxa_mmc_init(struct mmc *mmc) /* Mask all interrupts */ writel(~(MMC_I_MASK_TXFIFO_WR_REQ | MMC_I_MASK_RXFIFO_RD_REQ), - ®s->i_mask); + ®s->i_mask); + return 0; } +#if !CONFIG_IS_ENABLED(DM_MMC) +static int pxa_mmc_init(struct mmc *mmc) +{ + struct pxa_mmc_priv *priv = mmc->priv; + + return pxa_mmc_init_common(priv, mmc); +} + +static int pxa_mmc_request(struct mmc *mmc, struct mmc_cmd *cmd, + struct mmc_data *data) +{ + struct pxa_mmc_priv *priv = mmc->priv; + + return pxa_mmc_send_cmd_common(priv, mmc, cmd, data); +} + +static int pxa_mmc_set_ios(struct mmc *mmc) +{ + struct pxa_mmc_priv *priv = mmc->priv; + + return pxa_mmc_set_ios_common(priv, mmc); +} + static const struct mmc_ops pxa_mmc_ops = { .send_cmd = pxa_mmc_request, .set_ios = pxa_mmc_set_ios, @@ -386,7 +411,7 @@ int pxa_mmc_register(int card_index) { struct mmc *mmc; struct pxa_mmc_priv *priv; - uint32_t reg; + u32 reg; int ret = -ENOMEM; priv = malloc(sizeof(struct pxa_mmc_priv)); @@ -405,7 +430,7 @@ int pxa_mmc_register(int card_index) default: ret = -EINVAL; printf("PXA MMC: Invalid MMC controller ID (card_index = %d)\n", - card_index); + card_index); goto err1; } @@ -420,7 +445,7 @@ int pxa_mmc_register(int card_index) #endif mmc = mmc_create(&pxa_mmc_cfg, priv); - if (mmc == NULL) + if (!mmc) goto err1; return 0; @@ -430,3 +455,82 @@ err1: err0: return ret; } +#else /* !CONFIG_IS_ENABLED(DM_MMC) */ +static int pxa_mmc_probe(struct udevice *dev) +{ + struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); + struct pxa_mmc_plat *plat = dev_get_platdata(dev); + struct mmc_config *cfg = &plat->cfg; + struct mmc *mmc = &plat->mmc; + struct pxa_mmc_priv *priv = dev_get_priv(dev); + u32 reg; + + upriv->mmc = mmc; + + cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; + cfg->f_max = PXAMMC_MAX_SPEED; + cfg->f_min = PXAMMC_MIN_SPEED; + cfg->host_caps = PXAMMC_HOST_CAPS; + cfg->name = dev->name; + cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34; + + mmc->priv = priv; + + priv->regs = plat->base; + +#ifndef CONFIG_CPU_MONAHANS /* PXA2xx */ + reg = readl(CKEN); + reg |= CKEN12_MMC; + writel(reg, CKEN); +#else /* PXA3xx */ + reg = readl(CKENA); + reg |= CKENA_12_MMC0 | CKENA_13_MMC1; + writel(reg, CKENA); +#endif + + return pxa_mmc_init_common(priv, mmc); +} + +static int pxa_mmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, + struct mmc_data *data) +{ + struct pxa_mmc_plat *plat = dev_get_platdata(dev); + struct pxa_mmc_priv *priv = dev_get_priv(dev); + + return pxa_mmc_send_cmd_common(priv, &plat->mmc, cmd, data); +} + +static int pxa_mmc_set_ios(struct udevice *dev) +{ + struct pxa_mmc_plat *plat = dev_get_platdata(dev); + struct pxa_mmc_priv *priv = dev_get_priv(dev); + + return pxa_mmc_set_ios_common(priv, &plat->mmc); +} + +static const struct dm_mmc_ops pxa_mmc_ops = { + .get_cd = NULL, + .send_cmd = pxa_mmc_send_cmd, + .set_ios = pxa_mmc_set_ios, +}; + +#if CONFIG_IS_ENABLED(BLK) +static int pxa_mmc_bind(struct udevice *dev) +{ + struct pxa_mmc_plat *plat = dev_get_platdata(dev); + + return mmc_bind(dev, &plat->mmc, &plat->cfg); +} +#endif + +U_BOOT_DRIVER(pxa_mmc) = { +#if CONFIG_IS_ENABLED(BLK) + .bind = pxa_mmc_bind, +#endif + .id = UCLASS_MMC, + .name = "pxa_mmc", + .ops = &pxa_mmc_ops, + .priv_auto_alloc_size = sizeof(struct pxa_mmc_priv), + .probe = pxa_mmc_probe, +}; +#endif /* !CONFIG_IS_ENABLED(DM_MMC) */ diff --git a/drivers/mmc/zynq_sdhci.c b/drivers/mmc/zynq_sdhci.c index de404aa9560..43b9f215229 100644 --- a/drivers/mmc/zynq_sdhci.c +++ b/drivers/mmc/zynq_sdhci.c @@ -19,8 +19,6 @@ #include <sdhci.h> #include <zynqmp_tap_delay.h> -DECLARE_GLOBAL_DATA_PTR; - struct arasan_sdhci_plat { struct mmc_config cfg; struct mmc mmc; |