Merge branch 'master' of http://git.denx.de/u-boot-mmc
This commit is contained in:
commit
c69f6d04ec
@ -29,7 +29,6 @@ int atmel_sdhci_init(void *regbase, u32 id)
|
||||
host->name = "atmel_sdhci";
|
||||
host->ioaddr = regbase;
|
||||
host->quirks = 0;
|
||||
host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
|
||||
max_clk = at91_get_periph_generated_clk(id);
|
||||
if (!max_clk) {
|
||||
printf("%s: Failed to get the proper clock\n", __func__);
|
||||
|
@ -157,7 +157,7 @@ int bcm2835_sdhci_init(u32 regbase, u32 emmc_freq)
|
||||
bcm_host = calloc(1, sizeof(*bcm_host));
|
||||
if (!bcm_host) {
|
||||
printf("sdhci_host calloc fail!\n");
|
||||
return 1;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -184,7 +184,6 @@ int bcm2835_sdhci_init(u32 regbase, u32 emmc_freq)
|
||||
host->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
|
||||
host->ops = &bcm2835_ops;
|
||||
|
||||
host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
|
||||
add_sdhci(host, emmc_freq, MIN_FREQ);
|
||||
|
||||
return 0;
|
||||
|
@ -488,10 +488,10 @@ static const struct mmc_ops dwmci_ops = {
|
||||
};
|
||||
#endif
|
||||
|
||||
void dwmci_setup_cfg(struct mmc_config *cfg, const char *name, int buswidth,
|
||||
uint caps, u32 max_clk, u32 min_clk)
|
||||
void dwmci_setup_cfg(struct mmc_config *cfg, struct dwmci_host *host,
|
||||
u32 max_clk, u32 min_clk)
|
||||
{
|
||||
cfg->name = name;
|
||||
cfg->name = host->name;
|
||||
#ifndef CONFIG_DM_MMC_OPS
|
||||
cfg->ops = &dwmci_ops;
|
||||
#endif
|
||||
@ -500,9 +500,9 @@ void dwmci_setup_cfg(struct mmc_config *cfg, const char *name, int buswidth,
|
||||
|
||||
cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
|
||||
|
||||
cfg->host_caps = caps;
|
||||
cfg->host_caps = host->caps;
|
||||
|
||||
if (buswidth == 8) {
|
||||
if (host->buswidth == 8) {
|
||||
cfg->host_caps |= MMC_MODE_8BIT;
|
||||
cfg->host_caps &= ~MMC_MODE_4BIT;
|
||||
} else {
|
||||
@ -522,8 +522,7 @@ int dwmci_bind(struct udevice *dev, struct mmc *mmc, struct mmc_config *cfg)
|
||||
#else
|
||||
int add_dwmci(struct dwmci_host *host, u32 max_clk, u32 min_clk)
|
||||
{
|
||||
dwmci_setup_cfg(&host->cfg, host->name, host->buswidth, host->caps,
|
||||
max_clk, min_clk);
|
||||
dwmci_setup_cfg(&host->cfg, host, max_clk, min_clk);
|
||||
|
||||
host->mmc = mmc_create(&host->cfg, host);
|
||||
if (host->mmc == NULL)
|
||||
|
@ -271,8 +271,7 @@ static int exynos_dwmmc_probe(struct udevice *dev)
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
dwmci_setup_cfg(&plat->cfg, host->name, host->buswidth, host->caps,
|
||||
DWMMC_MAX_FREQ, DWMMC_MIN_FREQ);
|
||||
dwmci_setup_cfg(&plat->cfg, host, DWMMC_MAX_FREQ, DWMMC_MIN_FREQ);
|
||||
host->mmc = &plat->mmc;
|
||||
host->mmc->priv = &priv->host;
|
||||
host->priv = dev;
|
||||
|
@ -21,7 +21,7 @@ int ftsdc021_sdhci_init(u32 regbase)
|
||||
host = calloc(1, sizeof(struct sdhci_host));
|
||||
if (!host) {
|
||||
puts("sdh_host malloc fail!\n");
|
||||
return 1;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
host->name = "FTSDC021";
|
||||
|
@ -27,7 +27,7 @@ static int init_kona_mmc_core(struct sdhci_host *host)
|
||||
|
||||
if (sdhci_readb(host, SDHCI_SOFTWARE_RESET) & SDHCI_RESET_ALL) {
|
||||
printf("%s: sd host controller reset error\n", __func__);
|
||||
return 1;
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
/* For kona a hardware reset before anything else. */
|
||||
@ -39,7 +39,7 @@ static int init_kona_mmc_core(struct sdhci_host *host)
|
||||
do {
|
||||
if (timeout == 0) {
|
||||
printf("%s: reset timeout error\n", __func__);
|
||||
return 1;
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
timeout--;
|
||||
udelay(100);
|
||||
@ -67,7 +67,7 @@ static int init_kona_mmc_core(struct sdhci_host *host)
|
||||
while (!(sdhci_readl(host, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT)) {
|
||||
if (timeout == 0) {
|
||||
printf("%s: CARD DETECT timeout error\n", __func__);
|
||||
return 1;
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
timeout--;
|
||||
udelay(100);
|
||||
@ -127,11 +127,6 @@ int kona_sdhci_init(int dev_index, u32 min_clk, u32 quirks)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (quirks & SDHCI_QUIRK_REG32_RW)
|
||||
host->version = sdhci_readl(host, SDHCI_HOST_VERSION - 2) >> 16;
|
||||
else
|
||||
host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
|
||||
|
||||
add_sdhci(host, max_clk, min_clk);
|
||||
return ret;
|
||||
}
|
||||
|
@ -140,9 +140,6 @@ static int msm_sdc_probe(struct udevice *dev)
|
||||
writel(caps, host->ioaddr + SDHCI_VENDOR_SPEC_CAPABILITIES0);
|
||||
}
|
||||
|
||||
/* Set host controller version */
|
||||
host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
|
||||
|
||||
ret = sdhci_setup_cfg(&plat->cfg, host, 0, 0);
|
||||
host->mmc = &plat->mmc;
|
||||
if (ret)
|
||||
|
@ -71,7 +71,7 @@ int mv_sdh_init(unsigned long regbase, u32 max_clk, u32 min_clk, u32 quirks)
|
||||
host = (struct sdhci_host *)malloc(sizeof(struct sdhci_host));
|
||||
if (!host) {
|
||||
printf("sdh_host malloc fail!\n");
|
||||
return 1;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
host->name = MVSDH_NAME;
|
||||
@ -88,9 +88,5 @@ int mv_sdh_init(unsigned long regbase, u32 max_clk, u32 min_clk, u32 quirks)
|
||||
sdhci_mvebu_mbus_config((void __iomem *)regbase);
|
||||
}
|
||||
|
||||
if (quirks & SDHCI_QUIRK_REG32_RW)
|
||||
host->version = sdhci_readl(host, SDHCI_HOST_VERSION - 2) >> 16;
|
||||
else
|
||||
host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
|
||||
return add_sdhci(host, max_clk, min_clk);
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ int pci_mmc_init(const char *name, struct pci_device_id *mmc_supported)
|
||||
|
||||
mmc_host->name = name;
|
||||
dm_pci_read_config32(dev, PCI_BASE_ADDRESS_0, &iobase);
|
||||
mmc_host->ioaddr = (void *)iobase;
|
||||
mmc_host->ioaddr = (void *)(ulong)iobase;
|
||||
mmc_host->quirks = 0;
|
||||
ret = add_sdhci(mmc_host, 0, 0);
|
||||
if (ret)
|
||||
|
@ -129,8 +129,7 @@ static int rockchip_dwmmc_probe(struct udevice *dev)
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
dwmci_setup_cfg(&plat->cfg, dev->name, host->buswidth, host->caps,
|
||||
priv->minmax[1], priv->minmax[0]);
|
||||
dwmci_setup_cfg(&plat->cfg, host, priv->minmax[1], priv->minmax[0]);
|
||||
host->mmc = &plat->mmc;
|
||||
host->mmc->priv = &priv->host;
|
||||
host->mmc->dev = dev;
|
||||
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <malloc.h>
|
||||
#include <sdhci.h>
|
||||
#include <fdtdec.h>
|
||||
@ -16,6 +17,15 @@
|
||||
#include <errno.h>
|
||||
#include <asm/arch/pinmux.h>
|
||||
|
||||
#ifdef CONFIG_DM_MMC
|
||||
struct s5p_sdhci_plat {
|
||||
struct mmc_config cfg;
|
||||
struct mmc mmc;
|
||||
};
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
#endif
|
||||
|
||||
static char *S5P_NAME = "SAMSUNG SDHCI";
|
||||
static void s5p_sdhci_set_control_reg(struct sdhci_host *host)
|
||||
{
|
||||
@ -71,7 +81,6 @@ static int s5p_sdhci_core_init(struct sdhci_host *host)
|
||||
SDHCI_QUIRK_32BIT_DMA_ADDR |
|
||||
SDHCI_QUIRK_WAIT_SEND_CMD | SDHCI_QUIRK_USE_WIDE8;
|
||||
host->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
|
||||
host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
|
||||
|
||||
host->set_control_reg = &s5p_sdhci_set_control_reg;
|
||||
host->set_clock = set_mmc_clk;
|
||||
@ -79,7 +88,11 @@ static int s5p_sdhci_core_init(struct sdhci_host *host)
|
||||
if (host->bus_width == 8)
|
||||
host->host_caps |= MMC_MODE_8BIT;
|
||||
|
||||
#ifndef CONFIG_BLK
|
||||
return add_sdhci(host, 52000000, 400000);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int s5p_sdhci_init(u32 regbase, int index, int bus_width)
|
||||
@ -87,7 +100,7 @@ int s5p_sdhci_init(u32 regbase, int index, int bus_width)
|
||||
struct sdhci_host *host = calloc(1, sizeof(struct sdhci_host));
|
||||
if (!host) {
|
||||
printf("sdhci__host allocation fail!\n");
|
||||
return 1;
|
||||
return -ENOMEM;
|
||||
}
|
||||
host->ioaddr = (void *)regbase;
|
||||
host->index = index;
|
||||
@ -141,7 +154,7 @@ static int sdhci_get_config(const void *blob, int node, struct sdhci_host *host)
|
||||
dev_id = pinmux_decode_periph_id(blob, node);
|
||||
if (dev_id < PERIPH_ID_SDMMC0 && dev_id > PERIPH_ID_SDMMC3) {
|
||||
debug("MMC: Can't get device id\n");
|
||||
return -1;
|
||||
return -EINVAL;
|
||||
}
|
||||
host->index = dev_id - PERIPH_ID_SDMMC0;
|
||||
|
||||
@ -149,7 +162,7 @@ static int sdhci_get_config(const void *blob, int node, struct sdhci_host *host)
|
||||
bus_width = fdtdec_get_int(blob, node, "samsung,bus-width", 0);
|
||||
if (bus_width <= 0) {
|
||||
debug("MMC: Can't get bus-width\n");
|
||||
return -1;
|
||||
return -EINVAL;
|
||||
}
|
||||
host->bus_width = bus_width;
|
||||
|
||||
@ -157,7 +170,7 @@ static int sdhci_get_config(const void *blob, int node, struct sdhci_host *host)
|
||||
base = fdtdec_get_addr(blob, node, "reg");
|
||||
if (!base) {
|
||||
debug("MMC: Can't get base address\n");
|
||||
return -1;
|
||||
return -EINVAL;
|
||||
}
|
||||
host->ioaddr = (void *)base;
|
||||
|
||||
@ -215,3 +228,60 @@ int exynos_mmc_init(const void *blob)
|
||||
return process_nodes(blob, node_list, count);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DM_MMC
|
||||
static int s5p_sdhci_probe(struct udevice *dev)
|
||||
{
|
||||
struct s5p_sdhci_plat *plat = dev_get_platdata(dev);
|
||||
struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
|
||||
struct sdhci_host *host = dev_get_priv(dev);
|
||||
int ret;
|
||||
|
||||
ret = sdhci_get_config(gd->fdt_blob, dev->of_offset, host);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = do_sdhci_init(host);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = sdhci_setup_cfg(&plat->cfg, host, 52000000, 400000);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
host->mmc = &plat->mmc;
|
||||
host->mmc->priv = host;
|
||||
host->mmc->dev = dev;
|
||||
upriv->mmc = host->mmc;
|
||||
|
||||
return sdhci_probe(dev);
|
||||
}
|
||||
|
||||
static int s5p_sdhci_bind(struct udevice *dev)
|
||||
{
|
||||
struct s5p_sdhci_plat *plat = dev_get_platdata(dev);
|
||||
int ret;
|
||||
|
||||
ret = sdhci_bind(dev, &plat->mmc, &plat->cfg);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct udevice_id s5p_sdhci_ids[] = {
|
||||
{ .compatible = "samsung,exynos4412-sdhci"},
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(s5p_sdhci_drv) = {
|
||||
.name = "s5p_sdhci",
|
||||
.id = UCLASS_MMC,
|
||||
.of_match = s5p_sdhci_ids,
|
||||
.bind = s5p_sdhci_bind,
|
||||
.ops = &sdhci_ops,
|
||||
.probe = s5p_sdhci_probe,
|
||||
.priv_auto_alloc_size = sizeof(struct sdhci_host),
|
||||
.platdata_auto_alloc_size = sizeof(struct s5p_sdhci_plat),
|
||||
};
|
||||
#endif /* CONFIG_DM_MMC */
|
||||
|
@ -87,7 +87,7 @@ static int sdhci_transfer_data(struct sdhci_host *host, struct mmc_data *data,
|
||||
if (stat & SDHCI_INT_ERROR) {
|
||||
printf("%s: Error detected in status(0x%X)!\n",
|
||||
__func__, stat);
|
||||
return -1;
|
||||
return -EIO;
|
||||
}
|
||||
if (stat & rdy) {
|
||||
if (!(sdhci_readl(host, SDHCI_PRESENT_STATE) & mask))
|
||||
@ -110,7 +110,7 @@ static int sdhci_transfer_data(struct sdhci_host *host, struct mmc_data *data,
|
||||
udelay(10);
|
||||
else {
|
||||
printf("%s: Transfer data timeout\n", __func__);
|
||||
return -1;
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
} while (!(stat & SDHCI_INT_DATA_END));
|
||||
return 0;
|
||||
@ -303,7 +303,7 @@ static int sdhci_set_clock(struct mmc *mmc, unsigned int clock)
|
||||
if (timeout == 0) {
|
||||
printf("%s: Timeout to wait cmd & data inhibit\n",
|
||||
__func__);
|
||||
return -1;
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
timeout--;
|
||||
@ -374,7 +374,7 @@ static int sdhci_set_clock(struct mmc *mmc, unsigned int clock)
|
||||
if (timeout == 0) {
|
||||
printf("%s: Internal clock never stabilised.\n",
|
||||
__func__);
|
||||
return -1;
|
||||
return -EBUSY;
|
||||
}
|
||||
timeout--;
|
||||
udelay(1000);
|
||||
@ -477,7 +477,7 @@ static int sdhci_init(struct mmc *mmc)
|
||||
if (!aligned_buffer) {
|
||||
printf("%s: Aligned buffer alloc failed!!!\n",
|
||||
__func__);
|
||||
return -1;
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
@ -546,7 +546,11 @@ int sdhci_setup_cfg(struct mmc_config *cfg, struct sdhci_host *host,
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif
|
||||
host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
|
||||
if (host->quirks & SDHCI_QUIRK_REG32_RW)
|
||||
host->version =
|
||||
sdhci_readl(host, SDHCI_HOST_VERSION - 2) >> 16;
|
||||
else
|
||||
host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
|
||||
|
||||
cfg->name = host->name;
|
||||
#ifndef CONFIG_DM_MMC_OPS
|
||||
@ -627,7 +631,7 @@ int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk)
|
||||
host->mmc = mmc_create(&host->cfg, host);
|
||||
if (host->mmc == NULL) {
|
||||
printf("%s: mmc create fail!\n", __func__);
|
||||
return -1;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -111,8 +111,7 @@ static int socfpga_dwmmc_probe(struct udevice *dev)
|
||||
struct dwmci_host *host = &priv->host;
|
||||
|
||||
#ifdef CONFIG_BLK
|
||||
dwmci_setup_cfg(&plat->cfg, dev->name, host->buswidth, host->caps,
|
||||
host->bus_hz, 400000);
|
||||
dwmci_setup_cfg(&plat->cfg, host, host->bus_hz, 400000);
|
||||
host->mmc = &plat->mmc;
|
||||
#else
|
||||
int ret;
|
||||
|
@ -22,11 +22,6 @@ int spear_sdhci_init(u32 regbase, u32 max_clk, u32 min_clk, u32 quirks)
|
||||
host->ioaddr = (void *)regbase;
|
||||
host->quirks = quirks;
|
||||
|
||||
if (quirks & SDHCI_QUIRK_REG32_RW)
|
||||
host->version = sdhci_readl(host, SDHCI_HOST_VERSION - 2) >> 16;
|
||||
else
|
||||
host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
|
||||
|
||||
add_sdhci(host, max_clk, min_clk);
|
||||
return 0;
|
||||
}
|
||||
|
@ -36,8 +36,6 @@ static int arasan_sdhci_probe(struct udevice *dev)
|
||||
host->quirks |= SDHCI_QUIRK_NO_HISPD_BIT;
|
||||
#endif
|
||||
|
||||
host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
|
||||
|
||||
ret = sdhci_setup_cfg(&plat->cfg, host, CONFIG_ZYNQ_SDHCI_MAX_FREQ,
|
||||
CONFIG_ZYNQ_SDHCI_MIN_FREQ);
|
||||
host->mmc = &plat->mmc;
|
||||
|
@ -253,14 +253,12 @@ static inline u8 dwmci_readb(struct dwmci_host *host, int reg)
|
||||
* See rockchip_dw_mmc.c for an example.
|
||||
*
|
||||
* @cfg: Configuration structure to fill in (generally &plat->mmc)
|
||||
* @name: Device name (normally dev->name)
|
||||
* @buswidth: Bus width (in bits, such as 4 or 8)
|
||||
* @caps: Host capabilities (MMC_MODE_...)
|
||||
* @host: DWMMC host
|
||||
* @max_clk: Maximum supported clock speed in HZ (e.g. 150000000)
|
||||
* @min_clk: Minimum supported clock speed in HZ (e.g. 400000)
|
||||
*/
|
||||
void dwmci_setup_cfg(struct mmc_config *cfg, const char *name, int buswidth,
|
||||
uint caps, u32 max_clk, u32 min_clk);
|
||||
void dwmci_setup_cfg(struct mmc_config *cfg, struct dwmci_host *host,
|
||||
u32 max_clk, u32 min_clk);
|
||||
|
||||
/**
|
||||
* dwmci_bind() - Set up a new MMC block device
|
||||
|
Loading…
Reference in New Issue
Block a user