summaryrefslogtreecommitdiff
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
parent2f760735c170c854ffca76be5607cec5c56fdc4f (diff)
parentcd45d6f3955c919b7f10793014db3dbcfd7df3bb (diff)
downloadu-boot-40e362a9ab5f1d409822942ee89d4473c2e01ee6.tar.gz
Merge tag 'mmc-9-6-2019' of https://gitlab.denx.de/u-boot/custodians/u-boot-mmcWIP/08Sep2019
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>
-rw-r--r--arch/arm/dts/ast2500-evb.dts14
-rw-r--r--arch/arm/dts/ast2500-u-boot.dtsi16
-rw-r--r--arch/arm/include/asm/arch-aspeed/scu_ast2500.h3
-rw-r--r--arch/arm/include/asm/gpio.h3
-rw-r--r--configs/evb-ast2500_defconfig9
-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
-rw-r--r--include/dm/ofnode.h2
-rw-r--r--include/dm/read.h33
-rw-r--r--include/mmc.h12
23 files changed, 289 insertions, 66 deletions
diff --git a/arch/arm/dts/ast2500-evb.dts b/arch/arm/dts/ast2500-evb.dts
index ebf44fd707..4796ed445f 100644
--- a/arch/arm/dts/ast2500-evb.dts
+++ b/arch/arm/dts/ast2500-evb.dts
@@ -59,3 +59,17 @@
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_mac2link_default &pinctrl_mdio2_default>;
};
+
+&sdhci0 {
+ status = "okay";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sd1_default>;
+};
+
+&sdhci1 {
+ status = "okay";
+
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_sd2_default>;
+};
diff --git a/arch/arm/dts/ast2500-u-boot.dtsi b/arch/arm/dts/ast2500-u-boot.dtsi
index 7f80bad7d0..8ac4215745 100644
--- a/arch/arm/dts/ast2500-u-boot.dtsi
+++ b/arch/arm/dts/ast2500-u-boot.dtsi
@@ -34,6 +34,22 @@
apb {
u-boot,dm-pre-reloc;
+
+ sdhci0: sdhci@1e740100 {
+ compatible = "aspeed,ast2500-sdhci";
+ reg = <0x1e740100>;
+ #reset-cells = <1>;
+ clocks = <&scu BCLK_SDCLK>;
+ resets = <&rst AST_RESET_SDIO>;
+ };
+
+ sdhci1: sdhci@1e740200 {
+ compatible = "aspeed,ast2500-sdhci";
+ reg = <0x1e740200>;
+ #reset-cells = <1>;
+ clocks = <&scu BCLK_SDCLK>;
+ resets = <&rst AST_RESET_SDIO>;
+ };
};
};
diff --git a/arch/arm/include/asm/arch-aspeed/scu_ast2500.h b/arch/arm/include/asm/arch-aspeed/scu_ast2500.h
index 4988ced7dd..8db4901cc9 100644
--- a/arch/arm/include/asm/arch-aspeed/scu_ast2500.h
+++ b/arch/arm/include/asm/arch-aspeed/scu_ast2500.h
@@ -22,6 +22,8 @@
#define SCU_MPLL_POST_MASK (0x3f << SCU_MPLL_POST_SHIFT)
#define SCU_PCLK_DIV_SHIFT 23
#define SCU_PCLK_DIV_MASK (7 << SCU_PCLK_DIV_SHIFT)
+#define SCU_SDCLK_DIV_SHIFT 12
+#define SCU_SDCLK_DIV_MASK (7 << SCU_SDCLK_DIV_SHIFT)
#define SCU_HPLL_DENUM_SHIFT 0
#define SCU_HPLL_DENUM_MASK 0x1f
#define SCU_HPLL_NUM_SHIFT 5
@@ -107,6 +109,7 @@
#define SCU_CLKSTOP_MAC1 (1 << 20)
#define SCU_CLKSTOP_MAC2 (1 << 21)
+#define SCU_CLKSTOP_SDCLK (1 << 27)
#define SCU_D2PLL_EXT1_OFF (1 << 0)
#define SCU_D2PLL_EXT1_BYPASS (1 << 1)
diff --git a/arch/arm/include/asm/gpio.h b/arch/arm/include/asm/gpio.h
index b9461058ae..6ff5f42424 100644
--- a/arch/arm/include/asm/gpio.h
+++ b/arch/arm/include/asm/gpio.h
@@ -2,7 +2,8 @@
!defined(CONFIG_ARCH_K3) && !defined(CONFIG_ARCH_BCM6858) && \
!defined(CONFIG_ARCH_BCM63158) && !defined(CONFIG_ARCH_ROCKCHIP) && \
!defined(CONFIG_ARCH_LX2160A) && !defined(CONFIG_ARCH_LS1028A) && \
- !defined(CONFIG_ARCH_LS2080A) && !defined(CONFIG_ARCH_LS1088A)
+ !defined(CONFIG_ARCH_LS2080A) && !defined(CONFIG_ARCH_LS1088A) && \
+ !defined(CONFIG_ARCH_ASPEED)
#include <asm/arch/gpio.h>
#endif
#include <asm-generic/gpio.h>
diff --git a/configs/evb-ast2500_defconfig b/configs/evb-ast2500_defconfig
index 59d41cb568..299fbfe94a 100644
--- a/configs/evb-ast2500_defconfig
+++ b/configs/evb-ast2500_defconfig
@@ -16,6 +16,7 @@ CONFIG_HUSH_PARSER=y
CONFIG_CMD_I2C=y
CONFIG_CMD_DHCP=y
CONFIG_CMD_MII=y
+CONFIG_CMD_MMC=y
CONFIG_CMD_PING=y
CONFIG_DEFAULT_DEVICE_TREE="ast2500-evb"
CONFIG_NET_RANDOM_ETHADDR=y
@@ -23,7 +24,6 @@ CONFIG_REGMAP=y
CONFIG_CLK=y
CONFIG_DM_I2C=y
CONFIG_SYS_I2C_ASPEED=y
-# CONFIG_MMC is not set
CONFIG_PHY_REALTEK=y
CONFIG_DM_ETH=y
CONFIG_FTGMAC100=y
@@ -36,3 +36,10 @@ CONFIG_SYS_NS16550=y
CONFIG_SYSRESET=y
CONFIG_TIMER=y
CONFIG_WDT=y
+CONFIG_MMC=y
+CONFIG_DM_MMC=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_ASPEED=y
+CONFIG_MMC_VERBOSE=y
+CONFIG_OF_CONTROL=y
+CONFIG_OF_EMBED=y
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)
diff --git a/include/dm/ofnode.h b/include/dm/ofnode.h
index 4f89db44c1..5c4cbf0998 100644
--- a/include/dm/ofnode.h
+++ b/include/dm/ofnode.h
@@ -254,7 +254,7 @@ int ofnode_read_u64(ofnode node, const char *propname, u64 *outp);
* @def: default value to return if the property has no value
* @return property value, or @def if not found
*/
-int ofnode_read_u64_default(ofnode node, const char *propname, u64 def);
+u64 ofnode_read_u64_default(ofnode node, const char *propname, u64 def);
/**
* ofnode_read_string() - Read a string from a property
diff --git a/include/dm/read.h b/include/dm/read.h
index 0c62d62f11..803daf7620 100644
--- a/include/dm/read.h
+++ b/include/dm/read.h
@@ -44,6 +44,7 @@ static inline bool dev_of_valid(struct udevice *dev)
}
#ifndef CONFIG_DM_DEV_READ_INLINE
+
/**
* dev_read_u32() - read a 32-bit integer from a device's DT property
*
@@ -97,6 +98,26 @@ int dev_read_s32_default(struct udevice *dev, const char *propname, int def);
int dev_read_u32u(struct udevice *dev, const char *propname, uint *outp);
/**
+ * dev_read_u64() - read a 64-bit integer from a device's DT property
+ *
+ * @dev: device to read DT property from
+ * @propname: name of the property to read from
+ * @outp: place to put value (if found)
+ * @return 0 if OK, -ve on error
+ */
+int dev_read_u64(struct udevice *dev, const char *propname, u64 *outp);
+
+/**
+ * dev_read_u64_default() - read a 64-bit integer from a device's DT property
+ *
+ * @dev: device to read DT property from
+ * @propname: name of the property to read from
+ * @def: default value to return if the property has no value
+ * @return property value, or @def if not found
+ */
+u64 dev_read_u64_default(struct udevice *dev, const char *propname, u64 def);
+
+/**
* dev_read_string() - Read a string from a device's DT property
*
* @dev: device to read DT property from
@@ -601,6 +622,18 @@ static inline int dev_read_u32u(struct udevice *dev,
return 0;
}
+static inline int dev_read_u64(struct udevice *dev,
+ const char *propname, u64 *outp)
+{
+ return ofnode_read_u64(dev_ofnode(dev), propname, outp);
+}
+
+static inline u64 dev_read_u64_default(struct udevice *dev,
+ const char *propname, u64 def)
+{
+ return ofnode_read_u64_default(dev_ofnode(dev), propname, def);
+}
+
static inline const char *dev_read_string(struct udevice *dev,
const char *propname)
{
diff --git a/include/mmc.h b/include/mmc.h
index 46422f41a4..686ba00656 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -457,10 +457,10 @@ struct dm_mmc_ops {
*
* @dev: Device to check
* @state: target state
- * @timeout: timeout in us
+ * @timeout_us: timeout in us
* @return 0 if dat0 is in the target state, -ve on error
*/
- int (*wait_dat0)(struct udevice *dev, int state, int timeout);
+ int (*wait_dat0)(struct udevice *dev, int state, int timeout_us);
#if CONFIG_IS_ENABLED(MMC_HS400_ES_SUPPORT)
/* set_enhanced_strobe() - set HS400 enhanced strobe */
@@ -476,14 +476,14 @@ int dm_mmc_set_ios(struct udevice *dev);
int dm_mmc_get_cd(struct udevice *dev);
int dm_mmc_get_wp(struct udevice *dev);
int dm_mmc_execute_tuning(struct udevice *dev, uint opcode);
-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);
/* Transition functions for compatibility */
int mmc_set_ios(struct mmc *mmc);
int mmc_getcd(struct mmc *mmc);
int mmc_getwp(struct mmc *mmc);
int mmc_execute_tuning(struct mmc *mmc, uint opcode);
-int mmc_wait_dat0(struct mmc *mmc, int state, int timeout);
+int mmc_wait_dat0(struct mmc *mmc, int state, int timeout_us);
int mmc_set_enhanced_strobe(struct mmc *mmc);
#else
@@ -602,8 +602,8 @@ struct mmc {
u8 part_attr;
u8 wr_rel_set;
u8 part_config;
- u8 gen_cmd6_time;
- u8 part_switch_time;
+ u8 gen_cmd6_time; /* units: 10 ms */
+ u8 part_switch_time; /* units: 10 ms */
uint tran_speed;
uint legacy_speed; /* speed for the legacy mode provided by the card */
uint read_bl_len;