summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2019-09-08 21:14:22 -0400
committerTom Rini <trini@konsulko.com>2019-09-08 21:15:13 -0400
commit40e362a9ab5f1d409822942ee89d4473c2e01ee6 (patch)
treead63f4fdcc210a0a758e41528fb2f15ecedf6a31 /drivers
parent2f760735c170c854ffca76be5607cec5c56fdc4f (diff)
parentcd45d6f3955c919b7f10793014db3dbcfd7df3bb (diff)
Merge tag 'mmc-9-6-2019' of https://gitlab.denx.de/u-boot/custodians/u-boot-mmc
Bug fixes to mmc_spi Add Aspeed SD driver Fix dw_mmc timeout calculation Fix timeout values passed to mmc_wait_dat0 sdhci dt caps/mask update [trini: Fix evb-ast2500_defconfig CONFIG_MMC line] Signed-off-by: Tom Rini <trini@konsulko.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/clk/aspeed/clk_ast2500.c27
-rw-r--r--drivers/core/ofnode.c2
-rw-r--r--drivers/core/read.c10
-rw-r--r--drivers/mmc/Kconfig11
-rw-r--r--drivers/mmc/Makefile1
-rw-r--r--drivers/mmc/aspeed_sdhci.c90
-rw-r--r--drivers/mmc/dw_mmc.c5
-rw-r--r--drivers/mmc/mmc-uclass.c12
-rw-r--r--drivers/mmc/mmc.c24
-rw-r--r--drivers/mmc/mmc_spi.c35
-rw-r--r--drivers/mmc/mmc_write.c8
-rw-r--r--drivers/mmc/omap_hsmmc.c6
-rw-r--r--drivers/mmc/renesas-sdhi.c7
-rw-r--r--drivers/mmc/sdhci.c23
-rw-r--r--drivers/pinctrl/aspeed/pinctrl_ast2500.c2
15 files changed, 206 insertions, 57 deletions
diff --git a/drivers/clk/aspeed/clk_ast2500.c b/drivers/clk/aspeed/clk_ast2500.c
index dbee13a182..9249cf9cdf 100644
--- a/drivers/clk/aspeed/clk_ast2500.c
+++ b/drivers/clk/aspeed/clk_ast2500.c
@@ -143,6 +143,17 @@ static ulong ast2500_clk_get_rate(struct clk *clk)
rate = rate / apb_div;
}
break;
+ case BCLK_SDCLK:
+ {
+ ulong apb_div = 4 + 4 * ((readl(&priv->scu->clk_sel1)
+ & SCU_SDCLK_DIV_MASK)
+ >> SCU_SDCLK_DIV_SHIFT);
+ rate = ast2500_get_hpll_rate(clkin,
+ readl(&priv->
+ scu->h_pll_param));
+ rate = rate / apb_div;
+ }
+ break;
case PCLK_UART1:
rate = ast2500_get_uart_clk_rate(priv->scu, 1);
break;
@@ -436,6 +447,22 @@ static int ast2500_clk_enable(struct clk *clk)
struct ast2500_clk_priv *priv = dev_get_priv(clk->dev);
switch (clk->id) {
+ case BCLK_SDCLK:
+ if (readl(&priv->scu->clk_stop_ctrl1) & SCU_CLKSTOP_SDCLK) {
+ ast_scu_unlock(priv->scu);
+
+ setbits_le32(&priv->scu->sysreset_ctrl1,
+ SCU_SYSRESET_SDIO);
+ udelay(100);
+ clrbits_le32(&priv->scu->clk_stop_ctrl1,
+ SCU_CLKSTOP_SDCLK);
+ mdelay(10);
+ clrbits_le32(&priv->scu->sysreset_ctrl1,
+ SCU_SYSRESET_SDIO);
+
+ ast_scu_lock(priv->scu);
+ }
+ break;
/*
* For MAC clocks the clock rate is
* configured based on whether RGMII or RMII mode has been selected
diff --git a/drivers/core/ofnode.c b/drivers/core/ofnode.c
index e74a662d1d..7eca00cd66 100644
--- a/drivers/core/ofnode.c
+++ b/drivers/core/ofnode.c
@@ -79,7 +79,7 @@ int ofnode_read_u64(ofnode node, const char *propname, u64 *outp)
return 0;
}
-int ofnode_read_u64_default(ofnode node, const char *propname, u64 def)
+u64 ofnode_read_u64_default(ofnode node, const char *propname, u64 def)
{
assert(ofnode_valid(node));
ofnode_read_u64(node, propname, &def);
diff --git a/drivers/core/read.c b/drivers/core/read.c
index 8b5502de11..fb3dcd9a79 100644
--- a/drivers/core/read.c
+++ b/drivers/core/read.c
@@ -44,6 +44,16 @@ int dev_read_u32u(struct udevice *dev, const char *propname, uint *outp)
return 0;
}
+int dev_read_u64(struct udevice *dev, const char *propname, u64 *outp)
+{
+ return ofnode_read_u64(dev_ofnode(dev), propname, outp);
+}
+
+u64 dev_read_u64_default(struct udevice *dev, const char *propname, u64 def)
+{
+ return ofnode_read_u64_default(dev_ofnode(dev), propname, def);
+}
+
const char *dev_read_string(struct udevice *dev, const char *propname)
{
return ofnode_read_string(dev_ofnode(dev), propname);
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig
index 0ccb1ea701..8fb2bfa444 100644
--- a/drivers/mmc/Kconfig
+++ b/drivers/mmc/Kconfig
@@ -421,6 +421,17 @@ config SPL_MMC_SDHCI_ADMA
This enables support for the ADMA (Advanced DMA) defined
in the SD Host Controller Standard Specification Version 3.00 in SPL.
+config MMC_SDHCI_ASPEED
+ bool "Aspeed SDHCI controller"
+ depends on ARCH_ASPEED
+ depends on DM_MMC
+ depends on MMC_SDHCI
+ help
+ Enables support for the Aspeed SDHCI 2.0 controller present on Aspeed
+ SoCs. This device is compatible with SD 3.0 and/or MMC 4.3
+ specifications. On the AST2600, the device is also compatible with
+ MMC 5.1 and eMMC 3.0.
+
config MMC_SDHCI_ATMEL
bool "Atmel SDHCI controller support"
depends on ARCH_AT91
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index 6cc018bb67..5594195528 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_JZ47XX_MMC) += jz_mmc.o
# SDHCI
obj-$(CONFIG_MMC_SDHCI) += sdhci.o
+obj-$(CONFIG_MMC_SDHCI_ASPEED) += aspeed_sdhci.o
obj-$(CONFIG_MMC_SDHCI_ATMEL) += atmel_sdhci.o
obj-$(CONFIG_MMC_SDHCI_BCM2835) += bcm2835_sdhci.o
obj-$(CONFIG_MMC_SDHCI_BCMSTB) += bcmstb_sdhci.o
diff --git a/drivers/mmc/aspeed_sdhci.c b/drivers/mmc/aspeed_sdhci.c
new file mode 100644
index 0000000000..1321ec37e1
--- /dev/null
+++ b/drivers/mmc/aspeed_sdhci.c
@@ -0,0 +1,90 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2019 IBM Corp.
+ * Eddie James <eajames@linux.ibm.com>
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <malloc.h>
+#include <sdhci.h>
+
+struct aspeed_sdhci_plat {
+ struct mmc_config cfg;
+ struct mmc mmc;
+};
+
+static int aspeed_sdhci_probe(struct udevice *dev)
+{
+ struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
+ struct aspeed_sdhci_plat *plat = dev_get_platdata(dev);
+ struct sdhci_host *host = dev_get_priv(dev);
+ u32 max_clk;
+ struct clk clk;
+ int ret;
+
+ ret = clk_get_by_index(dev, 0, &clk);
+ if (ret)
+ return ret;
+
+ ret = clk_enable(&clk);
+ if (ret)
+ goto free;
+
+ host->name = dev->name;
+ host->ioaddr = (void *)devfdt_get_addr(dev);
+
+ max_clk = clk_get_rate(&clk);
+ if (IS_ERR_VALUE(max_clk)) {
+ ret = max_clk;
+ goto err;
+ }
+
+ host->max_clk = max_clk;
+ host->mmc = &plat->mmc;
+ host->mmc->dev = dev;
+ host->mmc->priv = host;
+ upriv->mmc = host->mmc;
+
+ ret = sdhci_setup_cfg(&plat->cfg, host, 0, 0);
+ if (ret)
+ goto err;
+
+ ret = sdhci_probe(dev);
+ if (ret)
+ goto err;
+
+ return 0;
+
+err:
+ clk_disable(&clk);
+free:
+ clk_free(&clk);
+ return ret;
+}
+
+static int aspeed_sdhci_bind(struct udevice *dev)
+{
+ struct aspeed_sdhci_plat *plat = dev_get_platdata(dev);
+
+ return sdhci_bind(dev, &plat->mmc, &plat->cfg);
+}
+
+static const struct udevice_id aspeed_sdhci_ids[] = {
+ { .compatible = "aspeed,ast2400-sdhci" },
+ { .compatible = "aspeed,ast2500-sdhci" },
+ { .compatible = "aspeed,ast2600-sdhci" },
+ { }
+};
+
+U_BOOT_DRIVER(aspeed_sdhci_drv) = {
+ .name = "aspeed_sdhci",
+ .id = UCLASS_MMC,
+ .of_match = aspeed_sdhci_ids,
+ .ops = &sdhci_ops,
+ .bind = aspeed_sdhci_bind,
+ .probe = aspeed_sdhci_probe,
+ .priv_auto_alloc_size = sizeof(struct sdhci_host),
+ .platdata_auto_alloc_size = sizeof(struct aspeed_sdhci_plat),
+};
diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
index 22f6c7eefd..ebe7bcdd90 100644
--- a/drivers/mmc/dw_mmc.c
+++ b/drivers/mmc/dw_mmc.c
@@ -119,11 +119,12 @@ static unsigned int dwmci_get_timeout(struct mmc *mmc, const unsigned int size)
{
unsigned int timeout;
- timeout = size * 8 * 1000; /* counting in bits and msec */
- timeout *= 2; /* wait twice as long */
+ timeout = size * 8; /* counting in bits */
+ timeout *= 10; /* wait 10 times as long */
timeout /= mmc->clock;
timeout /= mmc->bus_width;
timeout /= mmc->ddr_mode ? 2 : 1;
+ timeout *= 1000; /* counting in msec */
timeout = (timeout < 1000) ? 1000 : timeout;
return timeout;
diff --git a/drivers/mmc/mmc-uclass.c b/drivers/mmc/mmc-uclass.c
index 2b146ea43c..37c3843902 100644
--- a/drivers/mmc/mmc-uclass.c
+++ b/drivers/mmc/mmc-uclass.c
@@ -47,18 +47,18 @@ int mmc_set_ios(struct mmc *mmc)
return dm_mmc_set_ios(mmc->dev);
}
-int dm_mmc_wait_dat0(struct udevice *dev, int state, int timeout)
+int dm_mmc_wait_dat0(struct udevice *dev, int state, int timeout_us)
{
struct dm_mmc_ops *ops = mmc_get_ops(dev);
if (!ops->wait_dat0)
return -ENOSYS;
- return ops->wait_dat0(dev, state, timeout);
+ return ops->wait_dat0(dev, state, timeout_us);
}
-int mmc_wait_dat0(struct mmc *mmc, int state, int timeout)
+int mmc_wait_dat0(struct mmc *mmc, int state, int timeout_us)
{
- return dm_mmc_wait_dat0(mmc->dev, state, timeout);
+ return dm_mmc_wait_dat0(mmc->dev, state, timeout_us);
}
int dm_mmc_get_wp(struct udevice *dev)
@@ -427,10 +427,6 @@ U_BOOT_DRIVER(mmc_blk) = {
};
#endif /* CONFIG_BLK */
-U_BOOT_DRIVER(mmc) = {
- .name = "mmc",
- .id = UCLASS_MMC,
-};
UCLASS_DRIVER(mmc) = {
.id = UCLASS_MMC,
diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c
index eecc7d687e..c8f71cd0c1 100644
--- a/drivers/mmc/mmc.c
+++ b/drivers/mmc/mmc.c
@@ -31,7 +31,7 @@ static int mmc_select_mode_and_width(struct mmc *mmc, uint card_caps);
#if !CONFIG_IS_ENABLED(DM_MMC)
-static int mmc_wait_dat0(struct mmc *mmc, int state, int timeout)
+static int mmc_wait_dat0(struct mmc *mmc, int state, int timeout_us)
{
return -ENOSYS;
}
@@ -230,12 +230,12 @@ int mmc_send_status(struct mmc *mmc, unsigned int *status)
return -ECOMM;
}
-int mmc_poll_for_busy(struct mmc *mmc, int timeout)
+int mmc_poll_for_busy(struct mmc *mmc, int timeout_ms)
{
unsigned int status;
int err;
- err = mmc_wait_dat0(mmc, 1, timeout);
+ err = mmc_wait_dat0(mmc, 1, timeout_ms * 1000);
if (err != -ENOSYS)
return err;
@@ -256,13 +256,13 @@ int mmc_poll_for_busy(struct mmc *mmc, int timeout)
return -ECOMM;
}
- if (timeout-- <= 0)
+ if (timeout_ms-- <= 0)
break;
udelay(1000);
}
- if (timeout <= 0) {
+ if (timeout_ms <= 0) {
#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
pr_err("Timeout waiting card ready\n");
#endif
@@ -750,17 +750,17 @@ static int __mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value,
{
unsigned int status, start;
struct mmc_cmd cmd;
- int timeout = DEFAULT_CMD6_TIMEOUT_MS;
+ int timeout_ms = DEFAULT_CMD6_TIMEOUT_MS;
bool is_part_switch = (set == EXT_CSD_CMD_SET_NORMAL) &&
(index == EXT_CSD_PART_CONF);
int retries = 3;
int ret;
if (mmc->gen_cmd6_time)
- timeout = mmc->gen_cmd6_time * 10;
+ timeout_ms = mmc->gen_cmd6_time * 10;
if (is_part_switch && mmc->part_switch_time)
- timeout = mmc->part_switch_time * 10;
+ timeout_ms = mmc->part_switch_time * 10;
cmd.cmdidx = MMC_CMD_SWITCH;
cmd.resp_type = MMC_RSP_R1b;
@@ -778,7 +778,7 @@ static int __mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value,
start = get_timer(0);
/* poll dat0 for rdy/buys status */
- ret = mmc_wait_dat0(mmc, 1, timeout);
+ ret = mmc_wait_dat0(mmc, 1, timeout_ms * 1000);
if (ret && ret != -ENOSYS)
return ret;
@@ -788,11 +788,11 @@ static int __mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value,
* stated timeout to be sufficient.
*/
if (ret == -ENOSYS && !send_status)
- mdelay(timeout);
+ mdelay(timeout_ms);
/* Finally wait until the card is ready or indicates a failure
* to switch. It doesn't hurt to use CMD13 here even if send_status
- * is false, because by now (after 'timeout' ms) the bus should be
+ * is false, because by now (after 'timeout_ms' ms) the bus should be
* reliable.
*/
do {
@@ -806,7 +806,7 @@ static int __mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value,
if (!ret && (status & MMC_STATUS_RDY_FOR_DATA))
return 0;
udelay(100);
- } while (get_timer(start) < timeout);
+ } while (get_timer(start) < timeout_ms);
return -ETIMEDOUT;
}
diff --git a/drivers/mmc/mmc_spi.c b/drivers/mmc/mmc_spi.c
index 350812a04b..c693fb2d17 100644
--- a/drivers/mmc/mmc_spi.c
+++ b/drivers/mmc/mmc_spi.c
@@ -58,12 +58,15 @@
#define READ_TIMEOUT 3000000 /* 1 sec */
#define WRITE_TIMEOUT 3000000 /* 1 sec */
-struct mmc_spi_priv {
- struct spi_slave *spi;
+struct mmc_spi_plat {
struct mmc_config cfg;
struct mmc mmc;
};
+struct mmc_spi_priv {
+ struct spi_slave *spi;
+};
+
static int mmc_spi_sendcmd(struct udevice *dev,
ushort cmdidx, u32 cmdarg, u32 resp_type,
u8 *resp, u32 resp_size,
@@ -370,6 +373,7 @@ done:
static int mmc_spi_probe(struct udevice *dev)
{
struct mmc_spi_priv *priv = dev_get_priv(dev);
+ struct mmc_spi_plat *plat = dev_get_platdata(dev);
struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
char *name;
@@ -385,28 +389,28 @@ static int mmc_spi_probe(struct udevice *dev)
return -ENOMEM;
sprintf(name, "%s:%s", dev->parent->name, dev->name);
- priv->cfg.name = name;
- priv->cfg.host_caps = MMC_MODE_SPI;
- priv->cfg.voltages = MMC_SPI_VOLTAGE;
- priv->cfg.f_min = MMC_SPI_MIN_CLOCK;
- priv->cfg.f_max = priv->spi->max_hz;
- priv->cfg.part_type = PART_TYPE_DOS;
- priv->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
+ plat->cfg.name = name;
+ plat->cfg.host_caps = MMC_MODE_SPI;
+ plat->cfg.voltages = MMC_SPI_VOLTAGE;
+ plat->cfg.f_min = MMC_SPI_MIN_CLOCK;
+ plat->cfg.f_max = priv->spi->max_hz;
+ plat->cfg.part_type = PART_TYPE_DOS;
+ plat->cfg.b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
- priv->mmc.cfg = &priv->cfg;
- priv->mmc.priv = priv;
- priv->mmc.dev = dev;
+ plat->mmc.cfg = &plat->cfg;
+ plat->mmc.priv = priv;
+ plat->mmc.dev = dev;
- upriv->mmc = &priv->mmc;
+ upriv->mmc = &plat->mmc;
return 0;
}
static int mmc_spi_bind(struct udevice *dev)
{
- struct mmc_spi_priv *priv = dev_get_priv(dev);
+ struct mmc_spi_plat *plat = dev_get_platdata(dev);
- return mmc_bind(dev, &priv->mmc, &priv->cfg);
+ return mmc_bind(dev, &plat->mmc, &plat->cfg);
}
static const struct dm_mmc_ops mmc_spi_ops = {
@@ -426,5 +430,6 @@ U_BOOT_DRIVER(mmc_spi) = {
.ops = &mmc_spi_ops,
.probe = mmc_spi_probe,
.bind = mmc_spi_bind,
+ .platdata_auto_alloc_size = sizeof(struct mmc_spi_plat),
.priv_auto_alloc_size = sizeof(struct mmc_spi_priv),
};
diff --git a/drivers/mmc/mmc_write.c b/drivers/mmc/mmc_write.c
index 02648b0f50..b52ff9f3bc 100644
--- a/drivers/mmc/mmc_write.c
+++ b/drivers/mmc/mmc_write.c
@@ -79,7 +79,7 @@ ulong mmc_berase(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt)
u32 start_rem, blkcnt_rem;
struct mmc *mmc = find_mmc_device(dev_num);
lbaint_t blk = 0, blk_r = 0;
- int timeout = 1000;
+ int timeout_ms = 1000;
if (!mmc)
return -1;
@@ -119,7 +119,7 @@ ulong mmc_berase(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt)
blk += blk_r;
/* Waiting for the ready status */
- if (mmc_poll_for_busy(mmc, timeout))
+ if (mmc_poll_for_busy(mmc, timeout_ms))
return 0;
}
@@ -131,7 +131,7 @@ static ulong mmc_write_blocks(struct mmc *mmc, lbaint_t start,
{
struct mmc_cmd cmd;
struct mmc_data data;
- int timeout = 1000;
+ int timeout_ms = 1000;
if ((start + blkcnt) > mmc_get_blk_desc(mmc)->lba) {
printf("MMC: block number 0x" LBAF " exceeds max(0x" LBAF ")\n",
@@ -177,7 +177,7 @@ static ulong mmc_write_blocks(struct mmc *mmc, lbaint_t start,
}
/* Waiting for the ready status */
- if (mmc_poll_for_busy(mmc, timeout))
+ if (mmc_poll_for_busy(mmc, timeout_ms))
return 0;
return blkcnt;
diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c
index 3ea7f4e173..bade129aea 100644
--- a/drivers/mmc/omap_hsmmc.c
+++ b/drivers/mmc/omap_hsmmc.c
@@ -430,7 +430,7 @@ static void omap_hsmmc_conf_bus_power(struct mmc *mmc, uint signal_voltage)
writel(ac12, &mmc_base->ac12);
}
-static int omap_hsmmc_wait_dat0(struct udevice *dev, int state, int timeout)
+static int omap_hsmmc_wait_dat0(struct udevice *dev, int state, int timeout_us)
{
int ret = -ETIMEDOUT;
u32 con;
@@ -442,8 +442,8 @@ static int omap_hsmmc_wait_dat0(struct udevice *dev, int state, int timeout)
con = readl(&mmc_base->con);
writel(con | CON_CLKEXTFREE | CON_PADEN, &mmc_base->con);
- timeout = DIV_ROUND_UP(timeout, 10); /* check every 10 us. */
- while (timeout--) {
+ timeout_us = DIV_ROUND_UP(timeout_us, 10); /* check every 10 us. */
+ while (timeout_us--) {
dat0_high = !!(readl(&mmc_base->pstate) & PSTATE_DLEV_DAT0);
if (dat0_high == target_dat0_high) {
ret = 0;
diff --git a/drivers/mmc/renesas-sdhi.c b/drivers/mmc/renesas-sdhi.c
index 7c53aa221e..0cb65b480d 100644
--- a/drivers/mmc/renesas-sdhi.c
+++ b/drivers/mmc/renesas-sdhi.c
@@ -499,15 +499,16 @@ static int renesas_sdhi_set_ios(struct udevice *dev)
}
#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
-static int renesas_sdhi_wait_dat0(struct udevice *dev, int state, int timeout)
+static int renesas_sdhi_wait_dat0(struct udevice *dev, int state,
+ int timeout_us)
{
int ret = -ETIMEDOUT;
bool dat0_high;
bool target_dat0_high = !!state;
struct tmio_sd_priv *priv = dev_get_priv(dev);
- timeout = DIV_ROUND_UP(timeout, 10); /* check every 10 us. */
- while (timeout--) {
+ timeout_us = DIV_ROUND_UP(timeout_us, 10); /* check every 10 us. */
+ while (timeout_us--) {
dat0_high = !!(tmio_sd_readl(priv, TMIO_SD_INFO2) & TMIO_SD_INFO2_DAT0);
if (dat0_high == target_dat0_high) {
ret = 0;
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c
index 2779bca93f..fbc576fd72 100644
--- a/drivers/mmc/sdhci.c
+++ b/drivers/mmc/sdhci.c
@@ -711,17 +711,19 @@ int sdhci_setup_cfg(struct mmc_config *cfg, struct sdhci_host *host,
{
u32 caps, caps_1 = 0;
#if CONFIG_IS_ENABLED(DM_MMC)
- u32 mask[2] = {0};
- int ret;
- ret = dev_read_u32_array(host->mmc->dev, "sdhci-caps-mask",
- mask, 2);
- if (ret && ret != -1)
- return ret;
-
- caps = ~mask[1] & sdhci_readl(host, SDHCI_CAPABILITIES);
+ u64 dt_caps, dt_caps_mask;
+
+ dt_caps_mask = dev_read_u64_default(host->mmc->dev,
+ "sdhci-caps-mask", 0);
+ dt_caps = dev_read_u64_default(host->mmc->dev,
+ "sdhci-caps", 0);
+ caps = ~(u32)dt_caps_mask &
+ sdhci_readl(host, SDHCI_CAPABILITIES);
+ caps |= (u32)dt_caps;
#else
caps = sdhci_readl(host, SDHCI_CAPABILITIES);
#endif
+ debug("%s, caps: 0x%x\n", __func__, caps);
#ifdef CONFIG_MMC_SDHCI_SDMA
if (!(caps & SDHCI_CAN_DO_SDMA)) {
@@ -762,10 +764,13 @@ int sdhci_setup_cfg(struct mmc_config *cfg, struct sdhci_host *host,
/* Check whether the clock multiplier is supported or not */
if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) {
#if CONFIG_IS_ENABLED(DM_MMC)
- caps_1 = ~mask[0] & sdhci_readl(host, SDHCI_CAPABILITIES_1);
+ caps_1 = ~(u32)(dt_caps_mask >> 32) &
+ sdhci_readl(host, SDHCI_CAPABILITIES_1);
+ caps_1 |= (u32)(dt_caps >> 32);
#else
caps_1 = sdhci_readl(host, SDHCI_CAPABILITIES_1);
#endif
+ debug("%s, caps_1: 0x%x\n", __func__, caps_1);
host->clk_mul = (caps_1 & SDHCI_CLOCK_MUL_MASK) >>
SDHCI_CLOCK_MUL_SHIFT;
}
diff --git a/drivers/pinctrl/aspeed/pinctrl_ast2500.c b/drivers/pinctrl/aspeed/pinctrl_ast2500.c
index ed333b9c5c..a6e9c0d933 100644
--- a/drivers/pinctrl/aspeed/pinctrl_ast2500.c
+++ b/drivers/pinctrl/aspeed/pinctrl_ast2500.c
@@ -58,6 +58,8 @@ static const struct ast2500_group_config ast2500_groups[] = {
{ "MDIO1", 3, (1 << 31) | (1 << 30) },
{ "MAC2LINK", 1, (1 << 1) },
{ "MDIO2", 5, (1 << 2) },
+ { "SD1", 5, (1 << 0) },
+ { "SD2", 5, (1 << 1) },
};
static int ast2500_pinctrl_get_groups_count(struct udevice *dev)