aboutsummaryrefslogtreecommitdiff
path: root/drivers/mmc
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mmc')
-rw-r--r--drivers/mmc/arm_pl180_mmci.c1
-rw-r--r--drivers/mmc/aspeed_sdhci.c4
-rw-r--r--drivers/mmc/atmel_sdhci.c2
-rw-r--r--drivers/mmc/bcmstb_sdhci.c64
-rw-r--r--drivers/mmc/gen_atmel_mci.c19
-rw-r--r--drivers/mmc/msm_sdhci.c1
-rw-r--r--drivers/mmc/pic32_sdhci.c1
-rw-r--r--drivers/mmc/renesas-sdhi.c21
-rw-r--r--drivers/mmc/rockchip_sdhci.c9
-rw-r--r--drivers/mmc/snps_dw_mmc.c8
-rw-r--r--drivers/mmc/socfpga_dw_mmc.c1
-rw-r--r--drivers/mmc/stm32_sdmmc2.c4
-rw-r--r--drivers/mmc/uniphier-sd.c1
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;
}