mirror of
https://github.com/Fishwaldo/u-boot.git
synced 2025-03-18 13:11:31 +00:00
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>
This commit is contained in:
commit
40e362a9ab
23 changed files with 288 additions and 65 deletions
|
@ -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>;
|
||||
};
|
||||
|
|
|
@ -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>;
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
90
drivers/mmc/aspeed_sdhci.c
Normal file
90
drivers/mmc/aspeed_sdhci.c
Normal file
|
@ -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),
|
||||
};
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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),
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
u64 dt_caps, dt_caps_mask;
|
||||
|
||||
caps = ~mask[1] & sdhci_readl(host, SDHCI_CAPABILITIES);
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
@ -96,6 +97,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
|
||||
*
|
||||
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue