+// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2011, Marvell Semiconductor Inc.
* Lei Wen <leiwen@marvell.com>
*
- * SPDX-License-Identifier: GPL-2.0+
- *
* Back ported to the 8xx platform (from the 8260 platform) by
* Murray.Jensen@cmst.csiro.au, 27-Jan-01.
*/
do {
stat = sdhci_readl(host, SDHCI_INT_STATUS);
if (stat & SDHCI_INT_ERROR) {
- printf("%s: Error detected in status(0x%X)!\n",
- __func__, stat);
+ pr_debug("%s: Error detected in status(0x%X)!\n",
+ __func__, stat);
return -EIO;
}
if (!transfer_done && (stat & rdy)) {
#define SDHCI_CMD_DEFAULT_TIMEOUT 100
#define SDHCI_READ_STATUS_TIMEOUT 1000
-#ifdef CONFIG_DM_MMC_OPS
+#ifdef CONFIG_DM_MMC
static int sdhci_send_command(struct udevice *dev, struct mmc_cmd *cmd,
struct mmc_data *data)
{
u32 mask, flags, mode;
unsigned int time = 0, start_addr = 0;
int mmc_dev = mmc_get_blk_desc(mmc)->devnum;
- unsigned start = get_timer(0);
+ ulong start = get_timer(0);
/* Timeout unit - ms */
static unsigned int cmd_timeout = SDHCI_CMD_DEFAULT_TIMEOUT;
- sdhci_writel(host, SDHCI_INT_ALL_MASK, SDHCI_INT_STATUS);
mask = SDHCI_CMD_INHIBIT | SDHCI_DATA_INHIBIT;
/* We shouldn't wait for data inihibit for stop commands, even
though they might use busy signaling */
- if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION)
+ if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION ||
+ cmd->cmdidx == MMC_CMD_SEND_TUNING_BLOCK)
mask &= ~SDHCI_DATA_INHIBIT;
while (sdhci_readl(host, SDHCI_PRESENT_STATE) & mask) {
udelay(1000);
}
+ sdhci_writel(host, SDHCI_INT_ALL_MASK, SDHCI_INT_STATUS);
+
mask = SDHCI_INT_RESPONSE;
+ if (cmd->cmdidx == MMC_CMD_SEND_TUNING_BLOCK)
+ mask = SDHCI_INT_DATA_AVAIL;
+
if (!(cmd->resp_type & MMC_RSP_PRESENT))
flags = SDHCI_CMD_RESP_NONE;
else if (cmd->resp_type & MMC_RSP_136)
flags |= SDHCI_CMD_CRC;
if (cmd->resp_type & MMC_RSP_OPCODE)
flags |= SDHCI_CMD_INDEX;
- if (data)
+ if (data || cmd->cmdidx == MMC_CMD_SEND_TUNING_BLOCK)
flags |= SDHCI_CMD_DATA;
/* Set Transfer mode regarding to data flag */
- if (data != 0) {
+ if (data) {
sdhci_writeb(host, 0xe, SDHCI_TIMEOUT_CONTROL);
mode = SDHCI_TRNS_BLK_CNT_EN;
trans_bytes = data->blocks * data->blocksize;
sdhci_writel(host, cmd->cmdarg, SDHCI_ARGUMENT);
#ifdef CONFIG_MMC_SDHCI_SDMA
- if (data != 0) {
+ if (data) {
trans_bytes = ALIGN(trans_bytes, CONFIG_SYS_CACHELINE_SIZE);
flush_cache(start_addr, trans_bytes);
}
sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
}
-#ifdef CONFIG_DM_MMC_OPS
+#ifdef CONFIG_DM_MMC
static int sdhci_set_ios(struct udevice *dev)
{
struct mmc *mmc = mmc_get_mmc_dev(dev);
if (mmc->clock != host->clock)
sdhci_set_clock(mmc, mmc->clock);
+ if (mmc->clk_disable)
+ sdhci_set_clock(mmc, 0);
+
/* Set bus width */
ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
if (mmc->bus_width == 8) {
else
ctrl &= ~SDHCI_CTRL_HISPD;
- if (host->quirks & SDHCI_QUIRK_NO_HISPD_BIT)
+ if ((host->quirks & SDHCI_QUIRK_NO_HISPD_BIT) ||
+ (host->quirks & SDHCI_QUIRK_BROKEN_HISPD_MODE))
ctrl &= ~SDHCI_CTRL_HISPD;
sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
return 0;
}
-#ifdef CONFIG_DM_MMC_OPS
+#ifdef CONFIG_DM_MMC
int sdhci_probe(struct udevice *dev)
{
struct mmc *mmc = mmc_get_mmc_dev(dev);
host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
cfg->name = host->name;
-#ifndef CONFIG_DM_MMC_OPS
+#ifndef CONFIG_DM_MMC
cfg->ops = &sdhci_ops;
#endif
if (host->quirks & SDHCI_QUIRK_BROKEN_VOLTAGE)
cfg->voltages |= host->voltages;
- cfg->host_caps = MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_4BIT;
+ cfg->host_caps |= MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_4BIT;
/* Since Host Controller Version3.0 */
if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) {
cfg->host_caps &= ~MMC_MODE_8BIT;
}
+ if (host->quirks & SDHCI_QUIRK_BROKEN_HISPD_MODE) {
+ cfg->host_caps &= ~MMC_MODE_HS;
+ cfg->host_caps &= ~MMC_MODE_HS_52MHz;
+ }
+
if (host->host_caps)
cfg->host_caps |= host->host_caps;