mirror of
https://source.denx.de/u-boot/u-boot.git
synced 2025-08-18 05:07:00 +02:00
Merge tag 'mmc-2019-11-5' of https://gitlab.denx.de/u-boot/custodians/u-boot-mmc
- fsl_esdhc driver cleanup - fsl_esdhc_imx driver improvement and compatible string update
This commit is contained in:
commit
e64ebde12d
@ -25,13 +25,6 @@
|
|||||||
|
|
||||||
DECLARE_GLOBAL_DATA_PTR;
|
DECLARE_GLOBAL_DATA_PTR;
|
||||||
|
|
||||||
#define SDHCI_IRQ_EN_BITS (IRQSTATEN_CC | IRQSTATEN_TC | \
|
|
||||||
IRQSTATEN_CINT | \
|
|
||||||
IRQSTATEN_CTOE | IRQSTATEN_CCE | IRQSTATEN_CEBE | \
|
|
||||||
IRQSTATEN_CIE | IRQSTATEN_DTOE | IRQSTATEN_DCE | \
|
|
||||||
IRQSTATEN_DEBE | IRQSTATEN_BRR | IRQSTATEN_BWR | \
|
|
||||||
IRQSTATEN_DINT)
|
|
||||||
|
|
||||||
struct fsl_esdhc {
|
struct fsl_esdhc {
|
||||||
uint dsaddr; /* SDMA system address register */
|
uint dsaddr; /* SDMA system address register */
|
||||||
uint blkattr; /* Block attributes register */
|
uint blkattr; /* Block attributes register */
|
||||||
@ -82,8 +75,6 @@ struct fsl_esdhc_plat {
|
|||||||
* @mmc: mmc
|
* @mmc: mmc
|
||||||
* Following is used when Driver Model is enabled for MMC
|
* Following is used when Driver Model is enabled for MMC
|
||||||
* @dev: pointer for the device
|
* @dev: pointer for the device
|
||||||
* @non_removable: 0: removable; 1: non-removable
|
|
||||||
* @wp_enable: 1: enable checking wp; 0: no check
|
|
||||||
* @cd_gpio: gpio for card detection
|
* @cd_gpio: gpio for card detection
|
||||||
* @wp_gpio: gpio for write protection
|
* @wp_gpio: gpio for write protection
|
||||||
*/
|
*/
|
||||||
@ -92,13 +83,10 @@ struct fsl_esdhc_priv {
|
|||||||
unsigned int sdhc_clk;
|
unsigned int sdhc_clk;
|
||||||
struct clk per_clk;
|
struct clk per_clk;
|
||||||
unsigned int clock;
|
unsigned int clock;
|
||||||
unsigned int bus_width;
|
|
||||||
#if !CONFIG_IS_ENABLED(DM_MMC)
|
#if !CONFIG_IS_ENABLED(DM_MMC)
|
||||||
struct mmc *mmc;
|
struct mmc *mmc;
|
||||||
#endif
|
#endif
|
||||||
struct udevice *dev;
|
struct udevice *dev;
|
||||||
int non_removable;
|
|
||||||
int wp_enable;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Return the XFERTYP flags for a given command and data packet */
|
/* Return the XFERTYP flags for a given command and data packet */
|
||||||
@ -241,12 +229,10 @@ static int esdhc_setup_data(struct fsl_esdhc_priv *priv, struct mmc *mmc,
|
|||||||
#endif
|
#endif
|
||||||
if (wml_value > WML_WR_WML_MAX)
|
if (wml_value > WML_WR_WML_MAX)
|
||||||
wml_value = WML_WR_WML_MAX_VAL;
|
wml_value = WML_WR_WML_MAX_VAL;
|
||||||
if (priv->wp_enable) {
|
|
||||||
if ((esdhc_read32(®s->prsstat) &
|
if (!(esdhc_read32(®s->prsstat) & PRSSTAT_WPSPL)) {
|
||||||
PRSSTAT_WPSPL) == 0) {
|
printf("Can not write to locked SD card.\n");
|
||||||
printf("\nThe SD card is locked. Can not write to a locked card.\n\n");
|
return -EINVAL;
|
||||||
return -ETIMEDOUT;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
esdhc_clrsetbits32(®s->wml, WML_WR_WML_MASK,
|
esdhc_clrsetbits32(®s->wml, WML_WR_WML_MASK,
|
||||||
@ -636,236 +622,42 @@ static int esdhc_getcd_common(struct fsl_esdhc_priv *priv)
|
|||||||
if (CONFIG_ESDHC_DETECT_QUIRK)
|
if (CONFIG_ESDHC_DETECT_QUIRK)
|
||||||
return 1;
|
return 1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CONFIG_IS_ENABLED(DM_MMC)
|
|
||||||
if (priv->non_removable)
|
|
||||||
return 1;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
while (!(esdhc_read32(®s->prsstat) & PRSSTAT_CINS) && --timeout)
|
while (!(esdhc_read32(®s->prsstat) & PRSSTAT_CINS) && --timeout)
|
||||||
udelay(1000);
|
udelay(1000);
|
||||||
|
|
||||||
return timeout > 0;
|
return timeout > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int esdhc_reset(struct fsl_esdhc *regs)
|
static void fsl_esdhc_get_cfg_common(struct fsl_esdhc_priv *priv,
|
||||||
|
struct mmc_config *cfg)
|
||||||
{
|
{
|
||||||
ulong start;
|
struct fsl_esdhc *regs = priv->esdhc_regs;
|
||||||
|
u32 caps;
|
||||||
|
|
||||||
/* reset the controller */
|
|
||||||
esdhc_setbits32(®s->sysctl, SYSCTL_RSTA);
|
|
||||||
|
|
||||||
/* hardware clears the bit when it is done */
|
|
||||||
start = get_timer(0);
|
|
||||||
while ((esdhc_read32(®s->sysctl) & SYSCTL_RSTA)) {
|
|
||||||
if (get_timer(start) > 100) {
|
|
||||||
printf("MMC/SD: Reset never completed.\n");
|
|
||||||
return -ETIMEDOUT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !CONFIG_IS_ENABLED(DM_MMC)
|
|
||||||
static int esdhc_getcd(struct mmc *mmc)
|
|
||||||
{
|
|
||||||
struct fsl_esdhc_priv *priv = mmc->priv;
|
|
||||||
|
|
||||||
return esdhc_getcd_common(priv);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int esdhc_init(struct mmc *mmc)
|
|
||||||
{
|
|
||||||
struct fsl_esdhc_priv *priv = mmc->priv;
|
|
||||||
|
|
||||||
return esdhc_init_common(priv, mmc);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
|
|
||||||
struct mmc_data *data)
|
|
||||||
{
|
|
||||||
struct fsl_esdhc_priv *priv = mmc->priv;
|
|
||||||
|
|
||||||
return esdhc_send_cmd_common(priv, mmc, cmd, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int esdhc_set_ios(struct mmc *mmc)
|
|
||||||
{
|
|
||||||
struct fsl_esdhc_priv *priv = mmc->priv;
|
|
||||||
|
|
||||||
return esdhc_set_ios_common(priv, mmc);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct mmc_ops esdhc_ops = {
|
|
||||||
.getcd = esdhc_getcd,
|
|
||||||
.init = esdhc_init,
|
|
||||||
.send_cmd = esdhc_send_cmd,
|
|
||||||
.set_ios = esdhc_set_ios,
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int fsl_esdhc_init(struct fsl_esdhc_priv *priv,
|
|
||||||
struct fsl_esdhc_plat *plat)
|
|
||||||
{
|
|
||||||
struct mmc_config *cfg;
|
|
||||||
struct fsl_esdhc *regs;
|
|
||||||
u32 caps, voltage_caps;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (!priv)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
regs = priv->esdhc_regs;
|
|
||||||
|
|
||||||
/* First reset the eSDHC controller */
|
|
||||||
ret = esdhc_reset(regs);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
esdhc_setbits32(®s->sysctl, SYSCTL_PEREN | SYSCTL_HCKEN |
|
|
||||||
SYSCTL_IPGEN | SYSCTL_CKEN);
|
|
||||||
|
|
||||||
writel(SDHCI_IRQ_EN_BITS, ®s->irqstaten);
|
|
||||||
cfg = &plat->cfg;
|
|
||||||
#ifndef CONFIG_DM_MMC
|
|
||||||
memset(cfg, '\0', sizeof(*cfg));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
voltage_caps = 0;
|
|
||||||
caps = esdhc_read32(®s->hostcapblt);
|
caps = esdhc_read32(®s->hostcapblt);
|
||||||
|
|
||||||
#ifdef CONFIG_SYS_FSL_ERRATUM_ESDHC135
|
#ifdef CONFIG_SYS_FSL_ERRATUM_ESDHC135
|
||||||
caps = caps & ~(ESDHC_HOSTCAPBLT_SRS |
|
caps &= ~(HOSTCAPBLT_SRS | HOSTCAPBLT_VS18 | HOSTCAPBLT_VS30);
|
||||||
ESDHC_HOSTCAPBLT_VS18 | ESDHC_HOSTCAPBLT_VS30);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* T4240 host controller capabilities register should have VS33 bit */
|
|
||||||
#ifdef CONFIG_SYS_FSL_MMC_HAS_CAPBLT_VS33
|
#ifdef CONFIG_SYS_FSL_MMC_HAS_CAPBLT_VS33
|
||||||
caps = caps | ESDHC_HOSTCAPBLT_VS33;
|
caps |= HOSTCAPBLT_VS33;
|
||||||
#endif
|
#endif
|
||||||
|
if (caps & HOSTCAPBLT_VS18)
|
||||||
if (caps & ESDHC_HOSTCAPBLT_VS18)
|
cfg->voltages |= MMC_VDD_165_195;
|
||||||
voltage_caps |= MMC_VDD_165_195;
|
if (caps & HOSTCAPBLT_VS30)
|
||||||
if (caps & ESDHC_HOSTCAPBLT_VS30)
|
cfg->voltages |= MMC_VDD_29_30 | MMC_VDD_30_31;
|
||||||
voltage_caps |= MMC_VDD_29_30 | MMC_VDD_30_31;
|
if (caps & HOSTCAPBLT_VS33)
|
||||||
if (caps & ESDHC_HOSTCAPBLT_VS33)
|
cfg->voltages |= MMC_VDD_32_33 | MMC_VDD_33_34;
|
||||||
voltage_caps |= MMC_VDD_32_33 | MMC_VDD_33_34;
|
|
||||||
|
|
||||||
cfg->name = "FSL_SDHC";
|
cfg->name = "FSL_SDHC";
|
||||||
#if !CONFIG_IS_ENABLED(DM_MMC)
|
|
||||||
cfg->ops = &esdhc_ops;
|
|
||||||
#endif
|
|
||||||
#ifdef CONFIG_SYS_SD_VOLTAGE
|
|
||||||
cfg->voltages = CONFIG_SYS_SD_VOLTAGE;
|
|
||||||
#else
|
|
||||||
cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
|
|
||||||
#endif
|
|
||||||
if ((cfg->voltages & voltage_caps) == 0) {
|
|
||||||
printf("voltage not supported by controller\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (priv->bus_width == 8)
|
if (caps & HOSTCAPBLT_HSS)
|
||||||
cfg->host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT;
|
|
||||||
else if (priv->bus_width == 4)
|
|
||||||
cfg->host_caps = MMC_MODE_4BIT;
|
|
||||||
|
|
||||||
cfg->host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT;
|
|
||||||
|
|
||||||
if (priv->bus_width > 0) {
|
|
||||||
if (priv->bus_width < 8)
|
|
||||||
cfg->host_caps &= ~MMC_MODE_8BIT;
|
|
||||||
if (priv->bus_width < 4)
|
|
||||||
cfg->host_caps &= ~MMC_MODE_4BIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (caps & ESDHC_HOSTCAPBLT_HSS)
|
|
||||||
cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
|
cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
|
||||||
|
|
||||||
#ifdef CONFIG_ESDHC_DETECT_8_BIT_QUIRK
|
|
||||||
if (CONFIG_ESDHC_DETECT_8_BIT_QUIRK)
|
|
||||||
cfg->host_caps &= ~MMC_MODE_8BIT;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
cfg->f_min = 400000;
|
cfg->f_min = 400000;
|
||||||
cfg->f_max = min(priv->sdhc_clk, (u32)200000000);
|
cfg->f_max = min(priv->sdhc_clk, (u32)200000000);
|
||||||
|
|
||||||
cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
|
cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !CONFIG_IS_ENABLED(DM_MMC)
|
|
||||||
static int fsl_esdhc_cfg_to_priv(struct fsl_esdhc_cfg *cfg,
|
|
||||||
struct fsl_esdhc_priv *priv)
|
|
||||||
{
|
|
||||||
if (!cfg || !priv)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
priv->esdhc_regs = (struct fsl_esdhc *)(unsigned long)(cfg->esdhc_base);
|
|
||||||
priv->bus_width = cfg->max_bus_width;
|
|
||||||
priv->sdhc_clk = cfg->sdhc_clk;
|
|
||||||
priv->wp_enable = cfg->wp_enable;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
int fsl_esdhc_initialize(bd_t *bis, struct fsl_esdhc_cfg *cfg)
|
|
||||||
{
|
|
||||||
struct fsl_esdhc_plat *plat;
|
|
||||||
struct fsl_esdhc_priv *priv;
|
|
||||||
struct mmc *mmc;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (!cfg)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
priv = calloc(sizeof(struct fsl_esdhc_priv), 1);
|
|
||||||
if (!priv)
|
|
||||||
return -ENOMEM;
|
|
||||||
plat = calloc(sizeof(struct fsl_esdhc_plat), 1);
|
|
||||||
if (!plat) {
|
|
||||||
free(priv);
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = fsl_esdhc_cfg_to_priv(cfg, priv);
|
|
||||||
if (ret) {
|
|
||||||
debug("%s xlate failure\n", __func__);
|
|
||||||
free(plat);
|
|
||||||
free(priv);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = fsl_esdhc_init(priv, plat);
|
|
||||||
if (ret) {
|
|
||||||
debug("%s init failure\n", __func__);
|
|
||||||
free(plat);
|
|
||||||
free(priv);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
mmc = mmc_create(&plat->cfg, priv);
|
|
||||||
if (!mmc)
|
|
||||||
return -EIO;
|
|
||||||
|
|
||||||
priv->mmc = mmc;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int fsl_esdhc_mmc_init(bd_t *bis)
|
|
||||||
{
|
|
||||||
struct fsl_esdhc_cfg *cfg;
|
|
||||||
|
|
||||||
cfg = calloc(sizeof(struct fsl_esdhc_cfg), 1);
|
|
||||||
cfg->esdhc_base = CONFIG_SYS_FSL_ESDHC_ADDR;
|
|
||||||
cfg->sdhc_clk = gd->arch.sdhc_clk;
|
|
||||||
return fsl_esdhc_initialize(bis, cfg);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
|
#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
|
||||||
void mmc_adapter_card_type_ident(void)
|
void mmc_adapter_card_type_ident(void)
|
||||||
{
|
{
|
||||||
@ -939,7 +731,106 @@ void fdt_fixup_esdhc(void *blob, bd_t *bd)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CONFIG_IS_ENABLED(DM_MMC)
|
#if !CONFIG_IS_ENABLED(DM_MMC)
|
||||||
|
static int esdhc_getcd(struct mmc *mmc)
|
||||||
|
{
|
||||||
|
struct fsl_esdhc_priv *priv = mmc->priv;
|
||||||
|
|
||||||
|
return esdhc_getcd_common(priv);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int esdhc_init(struct mmc *mmc)
|
||||||
|
{
|
||||||
|
struct fsl_esdhc_priv *priv = mmc->priv;
|
||||||
|
|
||||||
|
return esdhc_init_common(priv, mmc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
|
||||||
|
struct mmc_data *data)
|
||||||
|
{
|
||||||
|
struct fsl_esdhc_priv *priv = mmc->priv;
|
||||||
|
|
||||||
|
return esdhc_send_cmd_common(priv, mmc, cmd, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int esdhc_set_ios(struct mmc *mmc)
|
||||||
|
{
|
||||||
|
struct fsl_esdhc_priv *priv = mmc->priv;
|
||||||
|
|
||||||
|
return esdhc_set_ios_common(priv, mmc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct mmc_ops esdhc_ops = {
|
||||||
|
.getcd = esdhc_getcd,
|
||||||
|
.init = esdhc_init,
|
||||||
|
.send_cmd = esdhc_send_cmd,
|
||||||
|
.set_ios = esdhc_set_ios,
|
||||||
|
};
|
||||||
|
|
||||||
|
int fsl_esdhc_initialize(bd_t *bis, struct fsl_esdhc_cfg *cfg)
|
||||||
|
{
|
||||||
|
struct fsl_esdhc_plat *plat;
|
||||||
|
struct fsl_esdhc_priv *priv;
|
||||||
|
struct mmc_config *mmc_cfg;
|
||||||
|
struct mmc *mmc;
|
||||||
|
|
||||||
|
if (!cfg)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
priv = calloc(sizeof(struct fsl_esdhc_priv), 1);
|
||||||
|
if (!priv)
|
||||||
|
return -ENOMEM;
|
||||||
|
plat = calloc(sizeof(struct fsl_esdhc_plat), 1);
|
||||||
|
if (!plat) {
|
||||||
|
free(priv);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
priv->esdhc_regs = (struct fsl_esdhc *)(unsigned long)(cfg->esdhc_base);
|
||||||
|
priv->sdhc_clk = cfg->sdhc_clk;
|
||||||
|
|
||||||
|
mmc_cfg = &plat->cfg;
|
||||||
|
|
||||||
|
if (cfg->max_bus_width == 8) {
|
||||||
|
mmc_cfg->host_caps |= MMC_MODE_1BIT | MMC_MODE_4BIT |
|
||||||
|
MMC_MODE_8BIT;
|
||||||
|
} else if (cfg->max_bus_width == 4) {
|
||||||
|
mmc_cfg->host_caps |= MMC_MODE_1BIT | MMC_MODE_4BIT;
|
||||||
|
} else if (cfg->max_bus_width == 1) {
|
||||||
|
mmc_cfg->host_caps |= MMC_MODE_1BIT;
|
||||||
|
} else {
|
||||||
|
mmc_cfg->host_caps |= MMC_MODE_1BIT | MMC_MODE_4BIT |
|
||||||
|
MMC_MODE_8BIT;
|
||||||
|
printf("No max bus width provided. Assume 8-bit supported.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_ESDHC_DETECT_8_BIT_QUIRK
|
||||||
|
if (CONFIG_ESDHC_DETECT_8_BIT_QUIRK)
|
||||||
|
mmc_cfg->host_caps &= ~MMC_MODE_8BIT;
|
||||||
|
#endif
|
||||||
|
mmc_cfg->ops = &esdhc_ops;
|
||||||
|
|
||||||
|
fsl_esdhc_get_cfg_common(priv, mmc_cfg);
|
||||||
|
|
||||||
|
mmc = mmc_create(mmc_cfg, priv);
|
||||||
|
if (!mmc)
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
|
priv->mmc = mmc;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fsl_esdhc_mmc_init(bd_t *bis)
|
||||||
|
{
|
||||||
|
struct fsl_esdhc_cfg *cfg;
|
||||||
|
|
||||||
|
cfg = calloc(sizeof(struct fsl_esdhc_cfg), 1);
|
||||||
|
cfg->esdhc_base = CONFIG_SYS_FSL_ESDHC_ADDR;
|
||||||
|
cfg->sdhc_clk = gd->arch.sdhc_clk;
|
||||||
|
return fsl_esdhc_initialize(bis, cfg);
|
||||||
|
}
|
||||||
|
#else /* DM_MMC */
|
||||||
#ifndef CONFIG_PPC
|
#ifndef CONFIG_PPC
|
||||||
#include <asm/arch/clock.h>
|
#include <asm/arch/clock.h>
|
||||||
#endif
|
#endif
|
||||||
@ -949,7 +840,6 @@ static int fsl_esdhc_probe(struct udevice *dev)
|
|||||||
struct fsl_esdhc_plat *plat = dev_get_platdata(dev);
|
struct fsl_esdhc_plat *plat = dev_get_platdata(dev);
|
||||||
struct fsl_esdhc_priv *priv = dev_get_priv(dev);
|
struct fsl_esdhc_priv *priv = dev_get_priv(dev);
|
||||||
fdt_addr_t addr;
|
fdt_addr_t addr;
|
||||||
unsigned int val;
|
|
||||||
struct mmc *mmc;
|
struct mmc *mmc;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -963,22 +853,6 @@ static int fsl_esdhc_probe(struct udevice *dev)
|
|||||||
#endif
|
#endif
|
||||||
priv->dev = dev;
|
priv->dev = dev;
|
||||||
|
|
||||||
val = dev_read_u32_default(dev, "bus-width", -1);
|
|
||||||
if (val == 8)
|
|
||||||
priv->bus_width = 8;
|
|
||||||
else if (val == 4)
|
|
||||||
priv->bus_width = 4;
|
|
||||||
else
|
|
||||||
priv->bus_width = 1;
|
|
||||||
|
|
||||||
if (dev_read_bool(dev, "non-removable")) {
|
|
||||||
priv->non_removable = 1;
|
|
||||||
} else {
|
|
||||||
priv->non_removable = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
priv->wp_enable = 1;
|
|
||||||
|
|
||||||
if (IS_ENABLED(CONFIG_CLK)) {
|
if (IS_ENABLED(CONFIG_CLK)) {
|
||||||
/* Assigned clock already set clock */
|
/* Assigned clock already set clock */
|
||||||
ret = clk_get_by_name(dev, "per", &priv->per_clk);
|
ret = clk_get_by_name(dev, "per", &priv->per_clk);
|
||||||
@ -1005,11 +879,7 @@ static int fsl_esdhc_probe(struct udevice *dev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = fsl_esdhc_init(priv, plat);
|
fsl_esdhc_get_cfg_common(priv, &plat->cfg);
|
||||||
if (ret) {
|
|
||||||
dev_err(dev, "fsl_esdhc_init failure\n");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
mmc_of_parse(dev, &plat->cfg);
|
mmc_of_parse(dev, &plat->cfg);
|
||||||
|
|
||||||
@ -1024,8 +894,12 @@ static int fsl_esdhc_probe(struct udevice *dev)
|
|||||||
|
|
||||||
static int fsl_esdhc_get_cd(struct udevice *dev)
|
static int fsl_esdhc_get_cd(struct udevice *dev)
|
||||||
{
|
{
|
||||||
|
struct fsl_esdhc_plat *plat = dev_get_platdata(dev);
|
||||||
struct fsl_esdhc_priv *priv = dev_get_priv(dev);
|
struct fsl_esdhc_priv *priv = dev_get_priv(dev);
|
||||||
|
|
||||||
|
if (plat->cfg.host_caps & MMC_CAP_NONREMOVABLE)
|
||||||
|
return 1;
|
||||||
|
|
||||||
return esdhc_getcd_common(priv);
|
return esdhc_getcd_common(priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -627,9 +627,6 @@ static void set_sysctl(struct fsl_esdhc_priv *priv, struct mmc *mmc, uint clock)
|
|||||||
int sdhc_clk = priv->sdhc_clk;
|
int sdhc_clk = priv->sdhc_clk;
|
||||||
uint clk;
|
uint clk;
|
||||||
|
|
||||||
if (clock < mmc->cfg->f_min)
|
|
||||||
clock = mmc->cfg->f_min;
|
|
||||||
|
|
||||||
while (sdhc_clk / (16 * pre_div * ddr_pre_div) > clock && pre_div < 256)
|
while (sdhc_clk / (16 * pre_div * ddr_pre_div) > clock && pre_div < 256)
|
||||||
pre_div *= 2;
|
pre_div *= 2;
|
||||||
|
|
||||||
@ -958,6 +955,7 @@ static int esdhc_set_ios_common(struct fsl_esdhc_priv *priv, struct mmc *mmc)
|
|||||||
{
|
{
|
||||||
struct fsl_esdhc *regs = priv->esdhc_regs;
|
struct fsl_esdhc *regs = priv->esdhc_regs;
|
||||||
int ret __maybe_unused;
|
int ret __maybe_unused;
|
||||||
|
u32 clock;
|
||||||
|
|
||||||
#ifdef CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK
|
#ifdef CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK
|
||||||
/* Select to use peripheral clock */
|
/* Select to use peripheral clock */
|
||||||
@ -966,8 +964,12 @@ static int esdhc_set_ios_common(struct fsl_esdhc_priv *priv, struct mmc *mmc)
|
|||||||
esdhc_clock_control(priv, true);
|
esdhc_clock_control(priv, true);
|
||||||
#endif
|
#endif
|
||||||
/* Set the clock speed */
|
/* Set the clock speed */
|
||||||
if (priv->clock != mmc->clock)
|
clock = mmc->clock;
|
||||||
set_sysctl(priv, mmc, mmc->clock);
|
if (clock < mmc->cfg->f_min)
|
||||||
|
clock = mmc->cfg->f_min;
|
||||||
|
|
||||||
|
if (priv->clock != clock)
|
||||||
|
set_sysctl(priv, mmc, clock);
|
||||||
|
|
||||||
#ifdef MMC_SUPPORTS_TUNING
|
#ifdef MMC_SUPPORTS_TUNING
|
||||||
if (mmc->clk_disable) {
|
if (mmc->clk_disable) {
|
||||||
@ -1645,6 +1647,9 @@ static const struct udevice_id fsl_esdhc_ids[] = {
|
|||||||
{ .compatible = "fsl,imx7d-usdhc", .data = (ulong)&usdhc_imx7d_data,},
|
{ .compatible = "fsl,imx7d-usdhc", .data = (ulong)&usdhc_imx7d_data,},
|
||||||
{ .compatible = "fsl,imx7ulp-usdhc", },
|
{ .compatible = "fsl,imx7ulp-usdhc", },
|
||||||
{ .compatible = "fsl,imx8qm-usdhc", .data = (ulong)&usdhc_imx8qm_data,},
|
{ .compatible = "fsl,imx8qm-usdhc", .data = (ulong)&usdhc_imx8qm_data,},
|
||||||
|
{ .compatible = "fsl,imx8mm-usdhc", .data = (ulong)&usdhc_imx8qm_data,},
|
||||||
|
{ .compatible = "fsl,imx8mn-usdhc", .data = (ulong)&usdhc_imx8qm_data,},
|
||||||
|
{ .compatible = "fsl,imx8mq-usdhc", .data = (ulong)&usdhc_imx8qm_data,},
|
||||||
{ .compatible = "fsl,esdhc", },
|
{ .compatible = "fsl,esdhc", },
|
||||||
{ /* sentinel */ }
|
{ /* sentinel */ }
|
||||||
};
|
};
|
||||||
|
@ -156,18 +156,18 @@
|
|||||||
#define BLKATTR_SIZE(x) (x & 0x1fff)
|
#define BLKATTR_SIZE(x) (x & 0x1fff)
|
||||||
#define MAX_BLK_CNT 0x7fff /* so malloc will have enough room with 32M */
|
#define MAX_BLK_CNT 0x7fff /* so malloc will have enough room with 32M */
|
||||||
|
|
||||||
#define ESDHC_HOSTCAPBLT_VS18 0x04000000
|
/* Host controller capabilities register */
|
||||||
#define ESDHC_HOSTCAPBLT_VS30 0x02000000
|
#define HOSTCAPBLT_VS18 0x04000000
|
||||||
#define ESDHC_HOSTCAPBLT_VS33 0x01000000
|
#define HOSTCAPBLT_VS30 0x02000000
|
||||||
#define ESDHC_HOSTCAPBLT_SRS 0x00800000
|
#define HOSTCAPBLT_VS33 0x01000000
|
||||||
#define ESDHC_HOSTCAPBLT_DMAS 0x00400000
|
#define HOSTCAPBLT_SRS 0x00800000
|
||||||
#define ESDHC_HOSTCAPBLT_HSS 0x00200000
|
#define HOSTCAPBLT_DMAS 0x00400000
|
||||||
|
#define HOSTCAPBLT_HSS 0x00200000
|
||||||
|
|
||||||
struct fsl_esdhc_cfg {
|
struct fsl_esdhc_cfg {
|
||||||
phys_addr_t esdhc_base;
|
phys_addr_t esdhc_base;
|
||||||
u32 sdhc_clk;
|
u32 sdhc_clk;
|
||||||
u8 max_bus_width;
|
u8 max_bus_width;
|
||||||
int wp_enable;
|
|
||||||
int vs18_enable; /* Use 1.8V if set to 1 */
|
int vs18_enable; /* Use 1.8V if set to 1 */
|
||||||
struct mmc_config cfg;
|
struct mmc_config cfg;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user