mmc: sdhci: Add support for auto-calibration
This patch adds Programmable Delay Line auto-calibration support if supported by respective hosts.If the host supports auto-calibration this change would enable sending CMD19/CMD21 before any read operation. CRs-Fixed: 516314 Change-Id: I8a0f51206dc0e174519dd71f0c75267a9e08e7f7 Signed-off-by: Asutosh Das <asutoshd@codeaurora.org> [subhashj@codeaurora.org: fixed minor merge conflict] Signed-off-by: Subhash Jadavani <subhashj@codeaurora.org>
This commit is contained in:
parent
d453e3e1ff
commit
d938b50db5
2 changed files with 41 additions and 0 deletions
|
@ -30,6 +30,7 @@
|
|||
#include <linux/mmc/card.h>
|
||||
#include <linux/mmc/sdio.h>
|
||||
#include <linux/mmc/slot-gpio.h>
|
||||
#include <linux/mmc/sdio.h>
|
||||
|
||||
#include "sdhci.h"
|
||||
|
||||
|
@ -1522,6 +1523,34 @@ static bool sdhci_check_state(struct sdhci_host *host)
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool sdhci_check_auto_tuning(struct sdhci_host *host,
|
||||
struct mmc_command *cmd)
|
||||
{
|
||||
if (((cmd->opcode != MMC_READ_SINGLE_BLOCK) &&
|
||||
(cmd->opcode != MMC_READ_MULTIPLE_BLOCK) &&
|
||||
(cmd->opcode != SD_IO_RW_EXTENDED)) || (host->clock < 100000000))
|
||||
return false;
|
||||
else if (host->mmc->ios.timing == MMC_TIMING_MMC_HS200 ||
|
||||
host->mmc->ios.timing == MMC_TIMING_UHS_SDR104)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
static int sdhci_get_tuning_cmd(struct sdhci_host *host)
|
||||
{
|
||||
if (!host->mmc || !host->mmc->card)
|
||||
return 0;
|
||||
/*
|
||||
* If we are here, all conditions have already been true
|
||||
* and the card can either be an eMMC or SD/SDIO
|
||||
*/
|
||||
if (mmc_card_mmc(host->mmc->card))
|
||||
return MMC_SEND_TUNING_BLOCK_HS200;
|
||||
else
|
||||
return MMC_SEND_TUNING_BLOCK;
|
||||
}
|
||||
|
||||
static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
|
||||
{
|
||||
struct sdhci_host *host;
|
||||
|
@ -1583,6 +1612,15 @@ static void sdhci_request(struct mmc_host *mmc, struct mmc_request *mrq)
|
|||
host->mrq->cmd->error = -ENOMEDIUM;
|
||||
tasklet_schedule(&host->finish_tasklet);
|
||||
} else {
|
||||
if (host->ops->config_auto_tuning_cmd) {
|
||||
if (sdhci_check_auto_tuning(host, mrq->cmd))
|
||||
host->ops->config_auto_tuning_cmd(host, true,
|
||||
sdhci_get_tuning_cmd(host));
|
||||
else
|
||||
host->ops->config_auto_tuning_cmd(host, false,
|
||||
sdhci_get_tuning_cmd(host));
|
||||
}
|
||||
|
||||
if (mrq->sbc && !(host->flags & SDHCI_AUTO_CMD23))
|
||||
sdhci_send_command(host, mrq->sbc);
|
||||
else
|
||||
|
|
|
@ -632,6 +632,9 @@ struct sdhci_ops {
|
|||
void (*card_event)(struct sdhci_host *host);
|
||||
void (*platform_bus_voting)(struct sdhci_host *host, u32 enable);
|
||||
void (*check_power_status)(struct sdhci_host *host, u32 req_type);
|
||||
int (*config_auto_tuning_cmd)(struct sdhci_host *host,
|
||||
bool enable,
|
||||
u32 type);
|
||||
void (*dump_vendor_regs)(struct sdhci_host *host);
|
||||
void (*voltage_switch)(struct sdhci_host *host);
|
||||
int (*select_drive_strength)(struct sdhci_host *host,
|
||||
|
|
Loading…
Add table
Reference in a new issue