mirror of
https://github.com/AsahiLinux/u-boot
synced 2025-03-01 13:57:24 +00:00
mmc: arm_pl180_mmci: Update to support CONFIG_BLK
Config flag CONFIG_BLK becomes mandatory, update arm_pl180_mmci to support this config. This driver is used by STM32Fx and by Vexpress platforms. Only STM32Fx are DM ready. No DM code is isolated and will be removed easily when wexpress will be converted to DM. Signed-off-by: Patrice Chotard <patrice.chotard@st.com>
This commit is contained in:
parent
d78bc42801
commit
8015093874
1 changed files with 40 additions and 27 deletions
|
@ -357,13 +357,13 @@ static const struct mmc_ops arm_pl180_mmci_ops = {
|
||||||
.set_ios = host_set_ios,
|
.set_ios = host_set_ios,
|
||||||
.init = mmc_host_reset,
|
.init = mmc_host_reset,
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* mmc_host_init - initialize the mmc controller.
|
* mmc_host_init - initialize the mmc controller.
|
||||||
* Set initial clock and power for mmc slot.
|
* Set initial clock and power for mmc slot.
|
||||||
* Initialize mmc struct and register with mmc framework.
|
* Initialize mmc struct and register with mmc framework.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int arm_pl180_mmci_init(struct pl180_mmc_host *host, struct mmc **mmc)
|
int arm_pl180_mmci_init(struct pl180_mmc_host *host, struct mmc **mmc)
|
||||||
{
|
{
|
||||||
u32 sdi_u32;
|
u32 sdi_u32;
|
||||||
|
@ -377,9 +377,8 @@ int arm_pl180_mmci_init(struct pl180_mmc_host *host, struct mmc **mmc)
|
||||||
writel(sdi_u32, &host->base->mask0);
|
writel(sdi_u32, &host->base->mask0);
|
||||||
|
|
||||||
host->cfg.name = host->name;
|
host->cfg.name = host->name;
|
||||||
#ifndef CONFIG_DM_MMC
|
|
||||||
host->cfg.ops = &arm_pl180_mmci_ops;
|
host->cfg.ops = &arm_pl180_mmci_ops;
|
||||||
#endif
|
|
||||||
/* TODO remove the duplicates */
|
/* TODO remove the duplicates */
|
||||||
host->cfg.host_caps = host->caps;
|
host->cfg.host_caps = host->caps;
|
||||||
host->cfg.voltages = host->voltages;
|
host->cfg.voltages = host->voltages;
|
||||||
|
@ -393,20 +392,34 @@ int arm_pl180_mmci_init(struct pl180_mmc_host *host, struct mmc **mmc)
|
||||||
*mmc = mmc_create(&host->cfg, host);
|
*mmc = mmc_create(&host->cfg, host);
|
||||||
if (!*mmc)
|
if (!*mmc)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
debug("registered mmc interface number is:%d\n",
|
debug("registered mmc interface number is:%d\n",
|
||||||
(*mmc)->block_dev.devnum);
|
(*mmc)->block_dev.devnum);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_DM_MMC
|
#ifdef CONFIG_DM_MMC
|
||||||
|
static void arm_pl180_mmc_init(struct pl180_mmc_host *host)
|
||||||
|
{
|
||||||
|
u32 sdi_u32;
|
||||||
|
|
||||||
|
writel(host->pwr_init, &host->base->power);
|
||||||
|
writel(host->clkdiv_init, &host->base->clock);
|
||||||
|
udelay(CLK_CHANGE_DELAY);
|
||||||
|
|
||||||
|
/* Disable mmc interrupts */
|
||||||
|
sdi_u32 = readl(&host->base->mask0) & ~SDI_MASK0_MASK;
|
||||||
|
writel(sdi_u32, &host->base->mask0);
|
||||||
|
}
|
||||||
|
|
||||||
static int arm_pl180_mmc_probe(struct udevice *dev)
|
static int arm_pl180_mmc_probe(struct udevice *dev)
|
||||||
{
|
{
|
||||||
struct arm_pl180_mmc_plat *pdata = dev_get_platdata(dev);
|
struct arm_pl180_mmc_plat *pdata = dev_get_platdata(dev);
|
||||||
struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
|
struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
|
||||||
struct mmc *mmc = &pdata->mmc;
|
struct mmc *mmc = &pdata->mmc;
|
||||||
struct pl180_mmc_host *host = mmc->priv;
|
struct pl180_mmc_host *host = dev->priv;
|
||||||
|
struct mmc_config *cfg = &pdata->cfg;
|
||||||
struct clk clk;
|
struct clk clk;
|
||||||
u32 bus_width;
|
u32 bus_width;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -421,27 +434,28 @@ static int arm_pl180_mmc_probe(struct udevice *dev)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
strcpy(host->name, "MMC");
|
|
||||||
host->pwr_init = INIT_PWR;
|
host->pwr_init = INIT_PWR;
|
||||||
host->clkdiv_init = SDI_CLKCR_CLKDIV_INIT_V1 | SDI_CLKCR_CLKEN |
|
host->clkdiv_init = SDI_CLKCR_CLKDIV_INIT_V1 | SDI_CLKCR_CLKEN |
|
||||||
SDI_CLKCR_HWFC_EN;
|
SDI_CLKCR_HWFC_EN;
|
||||||
host->voltages = VOLTAGE_WINDOW_SD;
|
|
||||||
host->caps = 0;
|
|
||||||
host->clock_in = clk_get_rate(&clk);
|
host->clock_in = clk_get_rate(&clk);
|
||||||
host->clock_min = host->clock_in / (2 * (SDI_CLKCR_CLKDIV_INIT_V1 + 1));
|
|
||||||
host->clock_max = dev_read_u32_default(dev, "max-frequency",
|
|
||||||
MMC_CLOCK_MAX);
|
|
||||||
host->version2 = dev_get_driver_data(dev);
|
host->version2 = dev_get_driver_data(dev);
|
||||||
|
|
||||||
|
cfg->name = dev->name;
|
||||||
|
cfg->voltages = VOLTAGE_WINDOW_SD;
|
||||||
|
cfg->host_caps = 0;
|
||||||
|
cfg->f_min = host->clock_in / (2 * (SDI_CLKCR_CLKDIV_INIT_V1 + 1));
|
||||||
|
cfg->f_max = dev_read_u32_default(dev, "max-frequency", MMC_CLOCK_MAX);
|
||||||
|
cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
|
||||||
|
|
||||||
gpio_request_by_name(dev, "cd-gpios", 0, &host->cd_gpio, GPIOD_IS_IN);
|
gpio_request_by_name(dev, "cd-gpios", 0, &host->cd_gpio, GPIOD_IS_IN);
|
||||||
|
|
||||||
bus_width = dev_read_u32_default(dev, "bus-width", 1);
|
bus_width = dev_read_u32_default(dev, "bus-width", 1);
|
||||||
switch (bus_width) {
|
switch (bus_width) {
|
||||||
case 8:
|
case 8:
|
||||||
host->caps |= MMC_MODE_8BIT;
|
cfg->host_caps |= MMC_MODE_8BIT;
|
||||||
/* Hosts capable of 8-bit transfers can also do 4 bits */
|
/* Hosts capable of 8-bit transfers can also do 4 bits */
|
||||||
case 4:
|
case 4:
|
||||||
host->caps |= MMC_MODE_4BIT;
|
cfg->host_caps |= MMC_MODE_4BIT;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
break;
|
break;
|
||||||
|
@ -449,19 +463,21 @@ static int arm_pl180_mmc_probe(struct udevice *dev)
|
||||||
dev_err(dev, "Invalid bus-width value %u\n", bus_width);
|
dev_err(dev, "Invalid bus-width value %u\n", bus_width);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = arm_pl180_mmci_init(host, &mmc);
|
arm_pl180_mmc_init(host);
|
||||||
if (ret) {
|
mmc->priv = host;
|
||||||
dev_err(dev, "arm_pl180_mmci init failed\n");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
mmc->dev = dev;
|
mmc->dev = dev;
|
||||||
dev->priv = host;
|
|
||||||
upriv->mmc = mmc;
|
upriv->mmc = mmc;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int arm_pl180_mmc_bind(struct udevice *dev)
|
||||||
|
{
|
||||||
|
struct arm_pl180_mmc_plat *plat = dev_get_platdata(dev);
|
||||||
|
|
||||||
|
return mmc_bind(dev, &plat->mmc, &plat->cfg);
|
||||||
|
}
|
||||||
|
|
||||||
static int dm_host_request(struct udevice *dev, struct mmc_cmd *cmd,
|
static int dm_host_request(struct udevice *dev, struct mmc_cmd *cmd,
|
||||||
struct mmc_data *data)
|
struct mmc_data *data)
|
||||||
{
|
{
|
||||||
|
@ -479,9 +495,7 @@ static int dm_host_set_ios(struct udevice *dev)
|
||||||
|
|
||||||
static int dm_mmc_getcd(struct udevice *dev)
|
static int dm_mmc_getcd(struct udevice *dev)
|
||||||
{
|
{
|
||||||
struct arm_pl180_mmc_plat *pdata = dev_get_platdata(dev);
|
struct pl180_mmc_host *host = dev->priv;
|
||||||
struct mmc *mmc = &pdata->mmc;
|
|
||||||
struct pl180_mmc_host *host = mmc->priv;
|
|
||||||
int value = 1;
|
int value = 1;
|
||||||
|
|
||||||
if (dm_gpio_is_valid(&host->cd_gpio)) {
|
if (dm_gpio_is_valid(&host->cd_gpio)) {
|
||||||
|
@ -501,12 +515,10 @@ static const struct dm_mmc_ops arm_pl180_dm_mmc_ops = {
|
||||||
|
|
||||||
static int arm_pl180_mmc_ofdata_to_platdata(struct udevice *dev)
|
static int arm_pl180_mmc_ofdata_to_platdata(struct udevice *dev)
|
||||||
{
|
{
|
||||||
struct arm_pl180_mmc_plat *pdata = dev_get_platdata(dev);
|
struct pl180_mmc_host *host = dev->priv;
|
||||||
struct mmc *mmc = &pdata->mmc;
|
|
||||||
struct pl180_mmc_host *host = mmc->priv;
|
|
||||||
fdt_addr_t addr;
|
fdt_addr_t addr;
|
||||||
|
|
||||||
addr = devfdt_get_addr(dev);
|
addr = dev_read_addr(dev);
|
||||||
if (addr == FDT_ADDR_T_NONE)
|
if (addr == FDT_ADDR_T_NONE)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
@ -527,6 +539,7 @@ U_BOOT_DRIVER(arm_pl180_mmc) = {
|
||||||
.ops = &arm_pl180_dm_mmc_ops,
|
.ops = &arm_pl180_dm_mmc_ops,
|
||||||
.probe = arm_pl180_mmc_probe,
|
.probe = arm_pl180_mmc_probe,
|
||||||
.ofdata_to_platdata = arm_pl180_mmc_ofdata_to_platdata,
|
.ofdata_to_platdata = arm_pl180_mmc_ofdata_to_platdata,
|
||||||
|
.bind = arm_pl180_mmc_bind,
|
||||||
.priv_auto_alloc_size = sizeof(struct pl180_mmc_host),
|
.priv_auto_alloc_size = sizeof(struct pl180_mmc_host),
|
||||||
.platdata_auto_alloc_size = sizeof(struct arm_pl180_mmc_plat),
|
.platdata_auto_alloc_size = sizeof(struct arm_pl180_mmc_plat),
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Reference in a new issue