mirror of
https://source.denx.de/u-boot/u-boot.git
synced 2026-06-02 09:46:37 +03:00
Merge tag 'mmc-next-2025-12-11' of https://source.denx.de/u-boot/custodians/u-boot-mmc into next
CI: https://source.denx.de/u-boot/custodians/u-boot-mmc/-/pipelines/28729 - mmc: assign f_max to 0 when max-frequency property not exist - Improvements and minor fixes for Cadence SDHCI driver
This commit is contained in:
@@ -243,8 +243,13 @@ int mmc_of_parse(struct udevice *dev, struct mmc_config *cfg)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* f_max is obtained from the optional "max-frequency" property */
|
||||
dev_read_u32(dev, "max-frequency", &cfg->f_max);
|
||||
/*
|
||||
* Maximum frequency is obtained from the optional "max-frequency" property.
|
||||
* If not specified in device tree, defaults to 0 and sdhci_setup_cfg()
|
||||
* will set the MMC configuration maximum frequency to the host controller's
|
||||
* maximum base clock frequency from capabilities register.
|
||||
*/
|
||||
cfg->f_max = dev_read_u32_default(dev, "max-frequency", 0);
|
||||
|
||||
if (dev_read_bool(dev, "cap-sd-highspeed"))
|
||||
cfg->host_caps |= MMC_CAP(SD_HS);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Socionext Inc.
|
||||
* Author: Masahiro Yamada <yamada.masahiro@socionext.com>
|
||||
* Copyright (C) 2025 Altera Corporation <www.altera.com>
|
||||
*/
|
||||
|
||||
#include <dm.h>
|
||||
@@ -15,6 +16,7 @@
|
||||
#include <linux/sizes.h>
|
||||
#include <linux/libfdt.h>
|
||||
#include <mmc.h>
|
||||
#include <reset.h>
|
||||
#include <sdhci.h>
|
||||
#include "sdhci-cadence.h"
|
||||
|
||||
@@ -83,39 +85,74 @@ static int sdhci_cdns_phy_init(struct sdhci_cdns_plat *plat,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int sdhci_cdns_get_hrs06_mode(struct mmc *mmc)
|
||||
{
|
||||
unsigned int mode;
|
||||
|
||||
if (IS_SD(mmc)) {
|
||||
mode = SDHCI_CDNS_HRS06_MODE_SD;
|
||||
} else {
|
||||
switch (mmc->selected_mode) {
|
||||
case MMC_LEGACY:
|
||||
mode = SDHCI_CDNS_HRS06_MODE_SD; /* use this for Legacy */
|
||||
break;
|
||||
|
||||
case MMC_HS:
|
||||
case MMC_HS_52:
|
||||
mode = SDHCI_CDNS_HRS06_MODE_MMC_SDR;
|
||||
break;
|
||||
|
||||
case UHS_DDR50:
|
||||
case MMC_DDR_52:
|
||||
mode = SDHCI_CDNS_HRS06_MODE_MMC_DDR;
|
||||
break;
|
||||
|
||||
case UHS_SDR104:
|
||||
case MMC_HS_200:
|
||||
mode = SDHCI_CDNS_HRS06_MODE_MMC_HS200;
|
||||
break;
|
||||
|
||||
case MMC_HS_400:
|
||||
case MMC_HS_400_ES:
|
||||
mode = SDHCI_CDNS_HRS06_MODE_MMC_HS400;
|
||||
break;
|
||||
|
||||
default:
|
||||
mode = SDHCI_CDNS_HRS06_MODE_SD;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return mode;
|
||||
}
|
||||
|
||||
static void sdhci_cdns_set_control_reg(struct sdhci_host *host)
|
||||
{
|
||||
struct mmc *mmc = host->mmc;
|
||||
struct sdhci_cdns_plat *plat = dev_get_plat(mmc->dev);
|
||||
unsigned int clock = mmc->clock;
|
||||
u32 mode, tmp;
|
||||
|
||||
/*
|
||||
* REVISIT:
|
||||
* The mode should be decided by MMC_TIMING_* like Linux, but
|
||||
* U-Boot does not support timing. Use the clock frequency instead.
|
||||
* Select HRS06 mode based on card type and selected timing mode.
|
||||
* For SD cards, always use SD mode (000b) as per Cadence user guide,
|
||||
* section 12.7 (HRS06), Part Number: IP6061.
|
||||
* For eMMC, use selected_mode to pick the appropriate mode.
|
||||
*/
|
||||
if (clock <= 26000000) {
|
||||
mode = SDHCI_CDNS_HRS06_MODE_SD; /* use this for Legacy */
|
||||
} else if (clock <= 52000000) {
|
||||
if (mmc->ddr_mode)
|
||||
mode = SDHCI_CDNS_HRS06_MODE_MMC_DDR;
|
||||
else
|
||||
mode = SDHCI_CDNS_HRS06_MODE_MMC_SDR;
|
||||
} else {
|
||||
if (mmc->ddr_mode)
|
||||
mode = SDHCI_CDNS_HRS06_MODE_MMC_HS400;
|
||||
else
|
||||
mode = SDHCI_CDNS_HRS06_MODE_MMC_HS200;
|
||||
}
|
||||
mode = sdhci_cdns_get_hrs06_mode(mmc);
|
||||
|
||||
tmp = readl(plat->hrs_addr + SDHCI_CDNS_HRS06);
|
||||
tmp &= ~SDHCI_CDNS_HRS06_MODE;
|
||||
tmp |= FIELD_PREP(SDHCI_CDNS_HRS06_MODE, mode);
|
||||
writel(tmp, plat->hrs_addr + SDHCI_CDNS_HRS06);
|
||||
|
||||
if (device_is_compatible(mmc->dev, "cdns,sd6hc"))
|
||||
sdhci_cdns6_phy_adj(mmc->dev, plat, mode);
|
||||
/*
|
||||
* For SD cards, program standard SDHCI Host Control2 UHS/voltage
|
||||
* registers for UHS-I support.
|
||||
*/
|
||||
if (IS_SD(mmc))
|
||||
sdhci_set_control_reg(host);
|
||||
|
||||
if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_420)
|
||||
sdhci_cdns6_phy_adj(mmc->dev, plat, mmc->selected_mode);
|
||||
}
|
||||
|
||||
static const struct sdhci_ops sdhci_cdns_ops = {
|
||||
@@ -125,11 +162,13 @@ static const struct sdhci_ops sdhci_cdns_ops = {
|
||||
static int sdhci_cdns_set_tune_val(struct sdhci_cdns_plat *plat,
|
||||
unsigned int val)
|
||||
{
|
||||
struct mmc *mmc = &plat->mmc;
|
||||
struct sdhci_host *host = dev_get_priv(mmc->dev);
|
||||
void __iomem *reg = plat->hrs_addr + SDHCI_CDNS_HRS06;
|
||||
u32 tmp;
|
||||
int i, ret;
|
||||
|
||||
if (device_is_compatible(plat->mmc.dev, "cdns,sd6hc"))
|
||||
if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_420)
|
||||
return sdhci_cdns6_set_tune_val(plat, val);
|
||||
|
||||
if (WARN_ON(!FIELD_FIT(SDHCI_CDNS_HRS06_TUNE, val)))
|
||||
@@ -168,16 +207,10 @@ static int __maybe_unused sdhci_cdns_execute_tuning(struct udevice *dev,
|
||||
int i;
|
||||
|
||||
/*
|
||||
* This handler only implements the eMMC tuning that is specific to
|
||||
* this controller. The tuning for SD timing should be handled by the
|
||||
* SDHCI core.
|
||||
* This function performs the tuning process for both SD and eMMC
|
||||
* interfaces. It sweeps through all available tuning points,
|
||||
* sending tuning commands at each step.
|
||||
*/
|
||||
if (!IS_MMC(mmc))
|
||||
return -ENOTSUPP;
|
||||
|
||||
if (WARN_ON(opcode != MMC_CMD_SEND_TUNING_BLOCK_HS200))
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < SDHCI_CDNS_MAX_TUNING_LOOP; i++) {
|
||||
if (sdhci_cdns_set_tune_val(plat, i) ||
|
||||
mmc_send_tuning(mmc, opcode)) { /* bad */
|
||||
@@ -214,6 +247,7 @@ static int sdhci_cdns_probe(struct udevice *dev)
|
||||
struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
|
||||
struct sdhci_cdns_plat *plat = dev_get_plat(dev);
|
||||
struct sdhci_host *host = dev_get_priv(dev);
|
||||
struct reset_ctl_bulk reset_bulk;
|
||||
fdt_addr_t base;
|
||||
int ret;
|
||||
|
||||
@@ -225,6 +259,10 @@ static int sdhci_cdns_probe(struct udevice *dev)
|
||||
if (!plat->hrs_addr)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = reset_get_bulk(dev, &reset_bulk);
|
||||
if (!ret)
|
||||
reset_deassert_bulk(&reset_bulk);
|
||||
|
||||
host->name = dev->name;
|
||||
host->ioaddr = plat->hrs_addr + SDHCI_CDNS_SRS_BASE;
|
||||
host->ops = &sdhci_cdns_ops;
|
||||
@@ -247,7 +285,7 @@ static int sdhci_cdns_probe(struct udevice *dev)
|
||||
|
||||
host->mmc = &plat->mmc;
|
||||
host->mmc->dev = dev;
|
||||
ret = sdhci_setup_cfg(&plat->cfg, host, 0, 0);
|
||||
ret = sdhci_setup_cfg(&plat->cfg, host, plat->cfg.f_max, 0);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Starfive.
|
||||
* Author: Kuan Lim Lee <kuanlim.lee@starfivetech.com>
|
||||
* Copyright (C) 2025 Altera Corporation <www.altera.com>
|
||||
*/
|
||||
|
||||
#include <dm.h>
|
||||
@@ -57,7 +58,7 @@
|
||||
#define PHY_DLL_SLAVE_CTRL_REG_READ_DQS_CMD_DELAY GENMASK(31, 24)
|
||||
#define PHY_DLL_SLAVE_CTRL_REG_READ_DQS_DELAY GENMASK(7, 0)
|
||||
|
||||
#define SDHCI_CDNS6_PHY_CFG_NUM 4
|
||||
#define SDHCI_CDNS6_PHY_CFG_NUM 5
|
||||
#define SDHCI_CDNS6_CTRL_CFG_NUM 4
|
||||
|
||||
struct sdhci_cdns6_phy_cfg {
|
||||
@@ -72,70 +73,90 @@ struct sdhci_cdns6_ctrl_cfg {
|
||||
|
||||
static struct sdhci_cdns6_phy_cfg sd_ds_phy_cfgs[] = {
|
||||
{ "cdns,phy-dqs-timing-delay-sd-ds", 0x00380004, },
|
||||
{ "cdns,phy-gate-lpbk_ctrl-delay-sd-ds", 0x01A00040, },
|
||||
{ "cdns,phy-gate-lpbk-ctrl-delay-sd-ds", 0x01A00040, },
|
||||
{ "cdns,phy-dll-slave-ctrl-sd-ds", 0x00000000, },
|
||||
{ "cdns,phy-dq-timing-delay-sd-ds", 0x00000001, },
|
||||
{ "cdns,phy-dll-master-ctrl-sd-ds", 0x00800004, },
|
||||
};
|
||||
|
||||
static struct sdhci_cdns6_phy_cfg sd_hs_phy_cfgs[] = {
|
||||
{ "cdns,phy-dqs-timing-delay-sd-hs", 0x00380004, },
|
||||
{ "cdns,phy-gate-lpbk-ctrl-delay-sd-hs", 0x01A00040, },
|
||||
{ "cdns,phy-dll-slave-ctrl-sd-hs", 0x00000000, },
|
||||
{ "cdns,phy-dq-timing-delay-sd-hs", 0x00000001, },
|
||||
{ "cdns,phy-dll-master-ctrl-sd-hs", 0x00800004, },
|
||||
};
|
||||
|
||||
static struct sdhci_cdns6_phy_cfg emmc_sdr_phy_cfgs[] = {
|
||||
{ "cdns,phy-dqs-timing-delay-semmc-sdr", 0x00380004, },
|
||||
{ "cdns,phy-gate-lpbk_ctrl-delay-emmc-sdr", 0x01A00040, },
|
||||
{ "cdns,phy-dqs-timing-delay-emmc-sdr", 0x00380004, },
|
||||
{ "cdns,phy-gate-lpbk-ctrl-delay-emmc-sdr", 0x01A00040, },
|
||||
{ "cdns,phy-dll-slave-ctrl-emmc-sdr", 0x00000000, },
|
||||
{ "cdns,phy-dq-timing-delay-emmc-sdr", 0x00000001, },
|
||||
{ "cdns,phy-dll-master-ctrl-emmc-sdr", 0x00800004, },
|
||||
};
|
||||
|
||||
static struct sdhci_cdns6_phy_cfg emmc_ddr_phy_cfgs[] = {
|
||||
{ "cdns,phy-dqs-timing-delay-emmc-ddr", 0x00380004, },
|
||||
{ "cdns,phy-gate-lpbk_ctrl-delay-emmc-ddr", 0x01A00040, },
|
||||
{ "cdns,phy-gate-lpbk-ctrl-delay-emmc-ddr", 0x01A00040, },
|
||||
{ "cdns,phy-dll-slave-ctrl-emmc-ddr", 0x00000000, },
|
||||
{ "cdns,phy-dq-timing-delay-emmc-ddr", 0x10000001, },
|
||||
{ "cdns,phy-dll-master-ctrl-emmc-ddr", 0x00800004, },
|
||||
};
|
||||
|
||||
static struct sdhci_cdns6_phy_cfg emmc_hs200_phy_cfgs[] = {
|
||||
{ "cdns,phy-dqs-timing-delay-emmc-hs200", 0x00380004, },
|
||||
{ "cdns,phy-gate-lpbk_ctrl-delay-emmc-hs200", 0x01A00040, },
|
||||
{ "cdns,phy-gate-lpbk-ctrl-delay-emmc-hs200", 0x01A00040, },
|
||||
{ "cdns,phy-dll-slave-ctrl-emmc-hs200", 0x00DADA00, },
|
||||
{ "cdns,phy-dq-timing-delay-emmc-hs200", 0x00000001, },
|
||||
{ "cdns,phy-dll-master-ctrl-emmc-hs200", 0x00000004, },
|
||||
};
|
||||
|
||||
static struct sdhci_cdns6_phy_cfg emmc_hs400_phy_cfgs[] = {
|
||||
{ "cdns,phy-dqs-timing-delay-emmc-hs400", 0x00280004, },
|
||||
{ "cdns,phy-gate-lpbk_ctrl-delay-emmc-hs400", 0x01A00040, },
|
||||
{ "cdns,phy-gate-lpbk-ctrl-delay-emmc-hs400", 0x01A00040, },
|
||||
{ "cdns,phy-dll-slave-ctrl-emmc-hs400", 0x00DAD800, },
|
||||
{ "cdns,phy-dq-timing-delay-emmc-hs400", 0x00000001, },
|
||||
{ "cdns,phy-dll-master-ctrl-emmc-hs400", 0x00000004, },
|
||||
};
|
||||
|
||||
static struct sdhci_cdns6_ctrl_cfg sd_ds_ctrl_cfgs[] = {
|
||||
{ "cdns,ctrl-hrs09-timing-delay-sd-ds", 0x0001800C, },
|
||||
{ "cdns,ctrl-hrs10-lpbk_ctrl-delay-sd-ds", 0x00020000, },
|
||||
{ "cdns,ctrl-hrs10-lpbk-ctrl-delay-sd-ds", 0x00020000, },
|
||||
{ "cdns,ctrl-hrs16-slave-ctrl-sd-ds", 0x00000000, },
|
||||
{ "cdns,ctrl-hrs07-timing-delay-sd-ds", 0x00080000, },
|
||||
};
|
||||
|
||||
static struct sdhci_cdns6_ctrl_cfg sd_hs_ctrl_cfgs[] = {
|
||||
{ "cdns,ctrl-hrs09-timing-delay-sd-hs", 0x0001800C, },
|
||||
{ "cdns,ctrl-hrs10-lpbk-ctrl-delay-sd-hs", 0x00030000, },
|
||||
{ "cdns,ctrl-hrs16-slave-ctrl-sd-hs", 0x00000000, },
|
||||
{ "cdns,ctrl-hrs07-timing-delay-sd-hs", 0x00080000, },
|
||||
};
|
||||
|
||||
static struct sdhci_cdns6_ctrl_cfg emmc_sdr_ctrl_cfgs[] = {
|
||||
{ "cdns,ctrl-hrs09-timing-delay-emmc-sdr", 0x0001800C, },
|
||||
{ "cdns,ctrl-hrs10-lpbk_ctrl-delay-emmc-sdr", 0x00030000, },
|
||||
{ "cdns,ctrl-hrs10-lpbk-ctrl-delay-emmc-sdr", 0x00030000, },
|
||||
{ "cdns,ctrl-hrs16-slave-ctrl-emmc-sdr", 0x00000000, },
|
||||
{ "cdns,ctrl-hrs07-timing-delay-emmc-sdr", 0x00080000, },
|
||||
};
|
||||
|
||||
static struct sdhci_cdns6_ctrl_cfg emmc_ddr_ctrl_cfgs[] = {
|
||||
{ "cdns,ctrl-hrs09-timing-delay-emmc-ddr", 0x0001800C, },
|
||||
{ "cdns,ctrl-hrs10-lpbk_ctrl-delay-emmc-ddr", 0x00020000, },
|
||||
{ "cdns,ctrl-hrs10-lpbk-ctrl-delay-emmc-ddr", 0x00020000, },
|
||||
{ "cdns,ctrl-hrs16-slave-ctrl-emmc-ddr", 0x11000001, },
|
||||
{ "cdns,ctrl-hrs07-timing-delay-emmc-ddr", 0x00090001, },
|
||||
};
|
||||
|
||||
static struct sdhci_cdns6_ctrl_cfg emmc_hs200_ctrl_cfgs[] = {
|
||||
{ "cdns,ctrl-hrs09-timing-delay-emmc-hs200", 0x00018000, },
|
||||
{ "cdns,ctrl-hrs10-lpbk_ctrl-delay-emmc-hs200", 0x00080000, },
|
||||
{ "cdns,ctrl-hrs10-lpbk-ctrl-delay-emmc-hs200", 0x00080000, },
|
||||
{ "cdns,ctrl-hrs16-slave-ctrl-emmc-hs200", 0x00000000, },
|
||||
{ "cdns,ctrl-hrs07-timing-delay-emmc-hs200", 0x00090000, },
|
||||
};
|
||||
|
||||
static struct sdhci_cdns6_ctrl_cfg emmc_hs400_ctrl_cfgs[] = {
|
||||
{ "cdns,ctrl-hrs09-timing-delay-emmc-hs400", 0x00018000, },
|
||||
{ "cdns,ctrl-hrs10-lpbk_ctrl-delay-emmc-hs400", 0x00080000, },
|
||||
{ "cdns,ctrl-hrs10-lpbk-ctrl-delay-emmc-hs400", 0x00080000, },
|
||||
{ "cdns,ctrl-hrs16-slave-ctrl-emmc-hs400", 0x11000000, },
|
||||
{ "cdns,ctrl-hrs07-timing-delay-emmc-hs400", 0x00080000, },
|
||||
};
|
||||
@@ -186,27 +207,39 @@ int sdhci_cdns6_phy_adj(struct udevice *dev, struct sdhci_cdns_plat *plat, u32 m
|
||||
int i, ret;
|
||||
|
||||
switch (mode) {
|
||||
case SDHCI_CDNS_HRS06_MODE_SD:
|
||||
case UHS_SDR12:
|
||||
case MMC_LEGACY:
|
||||
sdhci_cdns6_phy_cfgs = sd_ds_phy_cfgs;
|
||||
sdhci_cdns6_ctrl_cfgs = sd_ds_ctrl_cfgs;
|
||||
break;
|
||||
|
||||
case SDHCI_CDNS_HRS06_MODE_MMC_SDR:
|
||||
case SD_HS:
|
||||
case UHS_SDR25:
|
||||
case MMC_HS:
|
||||
sdhci_cdns6_phy_cfgs = sd_hs_phy_cfgs;
|
||||
sdhci_cdns6_ctrl_cfgs = sd_hs_ctrl_cfgs;
|
||||
break;
|
||||
|
||||
case UHS_SDR50:
|
||||
case MMC_HS_52:
|
||||
sdhci_cdns6_phy_cfgs = emmc_sdr_phy_cfgs;
|
||||
sdhci_cdns6_ctrl_cfgs = emmc_sdr_ctrl_cfgs;
|
||||
break;
|
||||
|
||||
case SDHCI_CDNS_HRS06_MODE_MMC_DDR:
|
||||
case UHS_DDR50:
|
||||
case MMC_DDR_52:
|
||||
sdhci_cdns6_phy_cfgs = emmc_ddr_phy_cfgs;
|
||||
sdhci_cdns6_ctrl_cfgs = emmc_ddr_ctrl_cfgs;
|
||||
break;
|
||||
|
||||
case SDHCI_CDNS_HRS06_MODE_MMC_HS200:
|
||||
case UHS_SDR104:
|
||||
case MMC_HS_200:
|
||||
sdhci_cdns6_phy_cfgs = emmc_hs200_phy_cfgs;
|
||||
sdhci_cdns6_ctrl_cfgs = emmc_hs200_ctrl_cfgs;
|
||||
break;
|
||||
|
||||
case SDHCI_CDNS_HRS06_MODE_MMC_HS400:
|
||||
case MMC_HS_400:
|
||||
case MMC_HS_400_ES:
|
||||
sdhci_cdns6_phy_cfgs = emmc_hs400_phy_cfgs;
|
||||
sdhci_cdns6_ctrl_cfgs = emmc_hs400_ctrl_cfgs;
|
||||
break;
|
||||
@@ -225,6 +258,7 @@ int sdhci_cdns6_phy_adj(struct udevice *dev, struct sdhci_cdns_plat *plat, u32 m
|
||||
|
||||
sdhci_cdns6_write_phy_reg(plat, PHY_DQS_TIMING_REG_ADDR, sdhci_cdns6_phy_cfgs[0].val);
|
||||
sdhci_cdns6_write_phy_reg(plat, PHY_GATE_LPBK_CTRL_REG_ADDR, sdhci_cdns6_phy_cfgs[1].val);
|
||||
sdhci_cdns6_write_phy_reg(plat, PHY_DLL_MASTER_CTRL_REG_ADDR, sdhci_cdns6_phy_cfgs[4].val);
|
||||
sdhci_cdns6_write_phy_reg(plat, PHY_DLL_SLAVE_CTRL_REG_ADDR, sdhci_cdns6_phy_cfgs[2].val);
|
||||
|
||||
/* Switch Off the DLL Reset */
|
||||
@@ -263,12 +297,13 @@ int sdhci_cdns6_phy_adj(struct udevice *dev, struct sdhci_cdns_plat *plat, u32 m
|
||||
|
||||
int sdhci_cdns6_phy_init(struct udevice *dev, struct sdhci_cdns_plat *plat)
|
||||
{
|
||||
return sdhci_cdns6_phy_adj(dev, plat, SDHCI_CDNS_HRS06_MODE_SD);
|
||||
return sdhci_cdns6_phy_adj(dev, plat, MMC_LEGACY);
|
||||
}
|
||||
|
||||
int sdhci_cdns6_set_tune_val(struct sdhci_cdns_plat *plat, unsigned int val)
|
||||
{
|
||||
u32 tmp, tuneval;
|
||||
int ret;
|
||||
|
||||
tuneval = (val * 256) / SDHCI_CDNS_MAX_TUNING_LOOP;
|
||||
|
||||
@@ -277,7 +312,18 @@ int sdhci_cdns6_set_tune_val(struct sdhci_cdns_plat *plat, unsigned int val)
|
||||
PHY_DLL_SLAVE_CTRL_REG_READ_DQS_DELAY);
|
||||
tmp |= FIELD_PREP(PHY_DLL_SLAVE_CTRL_REG_READ_DQS_CMD_DELAY, tuneval) |
|
||||
FIELD_PREP(PHY_DLL_SLAVE_CTRL_REG_READ_DQS_DELAY, tuneval);
|
||||
|
||||
/* Switch On the DLL Reset */
|
||||
sdhci_cdns6_reset_phy_dll(plat, true);
|
||||
|
||||
sdhci_cdns6_write_phy_reg(plat, PHY_DLL_SLAVE_CTRL_REG_ADDR, tmp);
|
||||
|
||||
/* Switch Off the DLL Reset */
|
||||
ret = sdhci_cdns6_reset_phy_dll(plat, false);
|
||||
if (ret) {
|
||||
printf("sdhci_cdns6_reset_phy is not completed\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -223,6 +223,9 @@
|
||||
#define SDHCI_SPEC_100 0
|
||||
#define SDHCI_SPEC_200 1
|
||||
#define SDHCI_SPEC_300 2
|
||||
#define SDHCI_SPEC_400 3
|
||||
#define SDHCI_SPEC_410 4
|
||||
#define SDHCI_SPEC_420 5
|
||||
|
||||
#define SDHCI_GET_VERSION(x) (x->version & SDHCI_SPEC_VER_MASK)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user