diff options
Diffstat (limited to 'drivers/mmc')
-rw-r--r-- | drivers/mmc/arm_pl180_mmci.c | 1 | ||||
-rw-r--r-- | drivers/mmc/aspeed_sdhci.c | 4 | ||||
-rw-r--r-- | drivers/mmc/atmel_sdhci.c | 2 | ||||
-rw-r--r-- | drivers/mmc/bcmstb_sdhci.c | 64 | ||||
-rw-r--r-- | drivers/mmc/gen_atmel_mci.c | 19 | ||||
-rw-r--r-- | drivers/mmc/msm_sdhci.c | 1 | ||||
-rw-r--r-- | drivers/mmc/pic32_sdhci.c | 1 | ||||
-rw-r--r-- | drivers/mmc/renesas-sdhi.c | 21 | ||||
-rw-r--r-- | drivers/mmc/rockchip_sdhci.c | 9 | ||||
-rw-r--r-- | drivers/mmc/snps_dw_mmc.c | 8 | ||||
-rw-r--r-- | drivers/mmc/socfpga_dw_mmc.c | 1 | ||||
-rw-r--r-- | drivers/mmc/stm32_sdmmc2.c | 4 | ||||
-rw-r--r-- | drivers/mmc/uniphier-sd.c | 1 |
13 files changed, 81 insertions, 55 deletions
diff --git a/drivers/mmc/arm_pl180_mmci.c b/drivers/mmc/arm_pl180_mmci.c index 9c5d48e90c..5cf5502ed5 100644 --- a/drivers/mmc/arm_pl180_mmci.c +++ b/drivers/mmc/arm_pl180_mmci.c @@ -447,7 +447,6 @@ static int arm_pl180_mmc_probe(struct udevice *dev) ret = clk_enable(&clk); if (ret) { - clk_free(&clk); dev_err(dev, "failed to enable clock\n"); return ret; } diff --git a/drivers/mmc/aspeed_sdhci.c b/drivers/mmc/aspeed_sdhci.c index 9d79bf58cc..c9626c6beb 100644 --- a/drivers/mmc/aspeed_sdhci.c +++ b/drivers/mmc/aspeed_sdhci.c @@ -35,7 +35,7 @@ static int aspeed_sdhci_probe(struct udevice *dev) ret = clk_enable(&clk); if (ret) { debug("%s: clock enable failed %d\n", __func__, ret); - goto free; + return ret; } host->name = dev->name; @@ -66,8 +66,6 @@ static int aspeed_sdhci_probe(struct udevice *dev) err: clk_disable(&clk); -free: - clk_free(&clk); return ret; } diff --git a/drivers/mmc/atmel_sdhci.c b/drivers/mmc/atmel_sdhci.c index 5347ba9043..d92bad97b7 100644 --- a/drivers/mmc/atmel_sdhci.c +++ b/drivers/mmc/atmel_sdhci.c @@ -147,8 +147,6 @@ static int atmel_sdhci_probe(struct udevice *dev) host->ops = &atmel_sdhci_ops; upriv->mmc = host->mmc; - clk_free(&clk); - ret = sdhci_probe(dev); if (ret) return ret; diff --git a/drivers/mmc/bcmstb_sdhci.c b/drivers/mmc/bcmstb_sdhci.c index dc96818cff..49846adcf5 100644 --- a/drivers/mmc/bcmstb_sdhci.c +++ b/drivers/mmc/bcmstb_sdhci.c @@ -38,15 +38,52 @@ */ #define BCMSTB_SDHCI_MINIMUM_CLOCK_FREQUENCY 400000 -/* - * This driver has only been tested with eMMC devices; SD devices may - * not work. - */ +#define SDIO_CFG_CTRL 0x0 +#define SDIO_CFG_CTRL_SDCD_N_TEST_EN BIT(31) +#define SDIO_CFG_CTRL_SDCD_N_TEST_LEV BIT(30) + +#define SDIO_CFG_SD_PIN_SEL 0x44 +#define SDIO_CFG_SD_PIN_SEL_MASK 0x3 +#define SDIO_CFG_SD_PIN_SEL_CARD BIT(1) + struct sdhci_bcmstb_plat { struct mmc_config cfg; struct mmc mmc; }; +struct sdhci_brcmstb_dev_priv { + int (*init)(struct udevice *dev); +}; + +static int sdhci_brcmstb_init_2712(struct udevice *dev) +{ + struct sdhci_host *host = dev_get_priv(dev); + void *cfg_regs; + u32 reg; + + /* Map in the non-standard CFG registers */ + cfg_regs = dev_remap_addr_name(dev, "cfg"); + if (!cfg_regs) + return -ENOENT; + + if ((host->mmc->host_caps & MMC_CAP_NONREMOVABLE) || + (host->mmc->host_caps & MMC_CAP_NEEDS_POLL)) { + /* Force presence */ + reg = readl(cfg_regs + SDIO_CFG_CTRL); + reg &= ~SDIO_CFG_CTRL_SDCD_N_TEST_LEV; + reg |= SDIO_CFG_CTRL_SDCD_N_TEST_EN; + writel(reg, cfg_regs + SDIO_CFG_CTRL); + } else { + /* Enable card detection line */ + reg = readl(cfg_regs + SDIO_CFG_SD_PIN_SEL); + reg &= ~SDIO_CFG_SD_PIN_SEL_MASK; + reg |= SDIO_CFG_SD_PIN_SEL_CARD; + writel(reg, cfg_regs + SDIO_CFG_SD_PIN_SEL); + } + + return 0; +} + static int sdhci_bcmstb_bind(struct udevice *dev) { struct sdhci_bcmstb_plat *plat = dev_get_plat(dev); @@ -54,14 +91,20 @@ static int sdhci_bcmstb_bind(struct udevice *dev) return sdhci_bind(dev, &plat->mmc, &plat->cfg); } +/* No specific SDHCI operations are required */ +static const struct sdhci_ops bcmstb_sdhci_ops = { 0 }; + static int sdhci_bcmstb_probe(struct udevice *dev) { struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); struct sdhci_bcmstb_plat *plat = dev_get_plat(dev); struct sdhci_host *host = dev_get_priv(dev); + struct sdhci_brcmstb_dev_priv *dev_priv; fdt_addr_t base; int ret; + dev_priv = (struct sdhci_brcmstb_dev_priv *)dev_get_driver_data(dev); + base = dev_read_addr(dev); if (base == FDT_ADDR_T_NONE) return -EINVAL; @@ -75,6 +118,8 @@ static int sdhci_bcmstb_probe(struct udevice *dev) host->mmc = &plat->mmc; host->mmc->dev = dev; + host->ops = &bcmstb_sdhci_ops; + ret = sdhci_setup_cfg(&plat->cfg, host, BCMSTB_SDHCI_MAXIMUM_CLOCK_FREQUENCY, BCMSTB_SDHCI_MINIMUM_CLOCK_FREQUENCY); @@ -84,10 +129,21 @@ static int sdhci_bcmstb_probe(struct udevice *dev) upriv->mmc = &plat->mmc; host->mmc->priv = host; + if (dev_priv && dev_priv->init) { + ret = dev_priv->init(dev); + if (ret) + return ret; + } + return sdhci_probe(dev); } +static const struct sdhci_brcmstb_dev_priv match_priv_2712 = { + .init = sdhci_brcmstb_init_2712, +}; + static const struct udevice_id sdhci_bcmstb_match[] = { + { .compatible = "brcm,bcm2712-sdhci", .data = (ulong)&match_priv_2712 }, { .compatible = "brcm,bcm7425-sdhci" }, { .compatible = "brcm,sdhci-brcmstb" }, { } diff --git a/drivers/mmc/gen_atmel_mci.c b/drivers/mmc/gen_atmel_mci.c index d91819acfd..3ee99558f6 100644 --- a/drivers/mmc/gen_atmel_mci.c +++ b/drivers/mmc/gen_atmel_mci.c @@ -559,27 +559,20 @@ static int atmel_mci_enable_clk(struct udevice *dev) int ret = 0; ret = clk_get_by_index(dev, 0, &clk); - if (ret) { - ret = -EINVAL; - goto failed; - } + if (ret) + return -EINVAL; ret = clk_enable(&clk); if (ret) - goto failed; + return ret; clk_rate = clk_get_rate(&clk); - if (!clk_rate) { - ret = -EINVAL; - goto failed; - } + if (!clk_rate) + return -EINVAL; priv->bus_clk_rate = clk_rate; -failed: - clk_free(&clk); - - return ret; + return 0; } static int atmel_mci_probe(struct udevice *dev) diff --git a/drivers/mmc/msm_sdhci.c b/drivers/mmc/msm_sdhci.c index 604f9c3ff9..fe1e754bfd 100644 --- a/drivers/mmc/msm_sdhci.c +++ b/drivers/mmc/msm_sdhci.c @@ -81,7 +81,6 @@ static int msm_sdc_clk_init(struct udevice *dev) return ret; ret = clk_set_rate(&clk, clk_rate); - clk_free(&clk); if (ret < 0) return ret; diff --git a/drivers/mmc/pic32_sdhci.c b/drivers/mmc/pic32_sdhci.c index fe555106a1..7a8e33dbc7 100644 --- a/drivers/mmc/pic32_sdhci.c +++ b/drivers/mmc/pic32_sdhci.c @@ -32,7 +32,6 @@ static int pic32_sdhci_probe(struct udevice *dev) return ret; clk_rate = clk_get_rate(&clk); - clk_free(&clk); if (IS_ERR_VALUE(clk_rate)) return clk_rate; diff --git a/drivers/mmc/renesas-sdhi.c b/drivers/mmc/renesas-sdhi.c index 97aaf1e4ec..a74559ca68 100644 --- a/drivers/mmc/renesas-sdhi.c +++ b/drivers/mmc/renesas-sdhi.c @@ -979,19 +979,19 @@ static int rzg2l_sdhi_setup(struct udevice *dev) ret = clk_get_by_name(dev, "cd", &imclk2); if (ret < 0) { dev_err(dev, "failed to get imclk2 (chip detect clk)\n"); - goto err_get_imclk2; + return ret; } ret = clk_get_by_name(dev, "aclk", &aclk); if (ret < 0) { dev_err(dev, "failed to get aclk\n"); - goto err_get_aclk; + return ret; } ret = clk_enable(&imclk2); if (ret < 0) { dev_err(dev, "failed to enable imclk2 (chip detect clk)\n"); - goto err_imclk2; + return ret; } ret = clk_enable(&aclk); @@ -1026,11 +1026,6 @@ err_get_reset: clk_disable(&aclk); err_aclk: clk_disable(&imclk2); -err_imclk2: - clk_free(&aclk); -err_get_aclk: - clk_free(&imclk2); -err_get_imclk2: return ret; } @@ -1071,7 +1066,7 @@ static int renesas_sdhi_probe(struct udevice *dev) ret = clk_set_rate(&priv->clkh, 800000000); if (ret < 0) { dev_err(dev, "failed to set rate for SDnH clock (%d)\n", ret); - goto err_clk; + return ret; } } @@ -1079,13 +1074,13 @@ static int renesas_sdhi_probe(struct udevice *dev) ret = clk_set_rate(&priv->clk, 200000000); if (ret < 0) { dev_err(dev, "failed to set rate for SDn clock (%d)\n", ret); - goto err_clkh; + return ret; } ret = clk_enable(&priv->clk); if (ret) { dev_err(dev, "failed to enable SDn clock (%d)\n", ret); - goto err_clkh; + return ret; } if (device_is_compatible(dev, "renesas,sdhi-r9a07g044")) @@ -1107,10 +1102,6 @@ static int renesas_sdhi_probe(struct udevice *dev) err_tmio_probe: clk_disable(&priv->clk); -err_clkh: - clk_free(&priv->clkh); -err_clk: - clk_free(&priv->clk); return ret; } diff --git a/drivers/mmc/rockchip_sdhci.c b/drivers/mmc/rockchip_sdhci.c index 285332d9f4..706fb12357 100644 --- a/drivers/mmc/rockchip_sdhci.c +++ b/drivers/mmc/rockchip_sdhci.c @@ -71,7 +71,6 @@ #define DLL_RXCLK_NO_INVERTER BIT(29) #define DLL_RXCLK_ORI_GATE BIT(31) #define DLL_TXCLK_TAPNUM_DEFAULT 0x10 -#define DLL_TXCLK_TAPNUM_90_DEGREES 0x9 #define DLL_TXCLK_TAPNUM_FROM_SW BIT(24) #define DLL_TXCLK_NO_INVERTER BIT(29) #define DLL_STRBIN_TAPNUM_DEFAULT 0x4 @@ -314,8 +313,10 @@ static int rk3568_sdhci_config_dll(struct sdhci_host *host, u32 clock, bool enab int val, ret; u32 extra, txclk_tapnum; - if (!enable) + if (!enable) { + sdhci_writel(host, 0, DWCMSHC_EMMC_DLL_CTRL); return 0; + } if (clock >= 100 * MHz) { /* reset DLL */ @@ -648,7 +649,7 @@ static const struct sdhci_data rk3568_data = { .config_dll = rk3568_sdhci_config_dll, .flags = FLAG_INVERTER_FLAG_IN_RXCLK, .hs200_txclk_tapnum = DLL_TXCLK_TAPNUM_DEFAULT, - .hs400_txclk_tapnum = DLL_TXCLK_TAPNUM_DEFAULT, + .hs400_txclk_tapnum = 0x8, }; static const struct sdhci_data rk3588_data = { @@ -656,7 +657,7 @@ static const struct sdhci_data rk3588_data = { .set_clock = rk3568_sdhci_set_clock, .config_dll = rk3568_sdhci_config_dll, .hs200_txclk_tapnum = DLL_TXCLK_TAPNUM_DEFAULT, - .hs400_txclk_tapnum = DLL_TXCLK_TAPNUM_90_DEGREES, + .hs400_txclk_tapnum = 0x9, }; static const struct udevice_id sdhci_ids[] = { diff --git a/drivers/mmc/snps_dw_mmc.c b/drivers/mmc/snps_dw_mmc.c index 50a8805e73..0134399e39 100644 --- a/drivers/mmc/snps_dw_mmc.c +++ b/drivers/mmc/snps_dw_mmc.c @@ -46,7 +46,7 @@ static int snps_dwmmc_clk_setup(struct udevice *dev) ret = clk_enable(&clk_ciu); if (ret && ret != -ENOSYS && ret != -ENOTSUPP) - goto clk_err_ciu; + goto clk_err; host->bus_hz = clk_get_rate(&clk_ciu); if (host->bus_hz < CLOCK_MIN) { @@ -60,16 +60,12 @@ static int snps_dwmmc_clk_setup(struct udevice *dev) ret = clk_enable(&clk_biu); if (ret && ret != -ENOSYS && ret != -ENOTSUPP) - goto clk_err_biu; + goto clk_err_ciu_dis; return 0; -clk_err_biu: - clk_free(&clk_biu); clk_err_ciu_dis: clk_disable(&clk_ciu); -clk_err_ciu: - clk_free(&clk_ciu); clk_err: dev_err(dev, "failed to setup clocks, ret %d\n", ret); diff --git a/drivers/mmc/socfpga_dw_mmc.c b/drivers/mmc/socfpga_dw_mmc.c index be3d8bfb3d..387cb8b6b5 100644 --- a/drivers/mmc/socfpga_dw_mmc.c +++ b/drivers/mmc/socfpga_dw_mmc.c @@ -99,7 +99,6 @@ static int socfpga_dwmmc_get_clk_rate(struct udevice *dev) host->bus_hz = clk_get_rate(&clk); - clk_free(&clk); #else /* Fixed clock divide by 4 which due to the SDMMC wrapper */ host->bus_hz = cm_get_mmc_controller_clk_hz(); diff --git a/drivers/mmc/stm32_sdmmc2.c b/drivers/mmc/stm32_sdmmc2.c index 5ff5e1a4d8..a2b111a843 100644 --- a/drivers/mmc/stm32_sdmmc2.c +++ b/drivers/mmc/stm32_sdmmc2.c @@ -766,10 +766,8 @@ static int stm32_sdmmc2_probe(struct udevice *dev) int ret; ret = clk_enable(&plat->clk); - if (ret) { - clk_free(&plat->clk); + if (ret) return ret; - } upriv->mmc = &plat->mmc; diff --git a/drivers/mmc/uniphier-sd.c b/drivers/mmc/uniphier-sd.c index 75003a0113..8cde4308aa 100644 --- a/drivers/mmc/uniphier-sd.c +++ b/drivers/mmc/uniphier-sd.c @@ -64,7 +64,6 @@ static int uniphier_sd_probe(struct udevice *dev) ret = clk_set_rate(&priv->clk, ULONG_MAX); if (ret < 0) { dev_err(dev, "failed to set rate for host clock\n"); - clk_free(&priv->clk); return ret; } |