summaryrefslogtreecommitdiffstats
path: root/drivers/mmc/host
diff options
context:
space:
mode:
authorWolfram Sang <wsa+renesas@sang-engineering.com>2020-11-25 22:30:00 +0100
committerUlf Hansson <ulf.hansson@linaro.org>2020-12-04 13:30:04 +0100
commit58959f89dd3d8cc8bedcd2d665496603098b29a2 (patch)
tree3843a3c0575b4f51f0edfee06d81362fbb2fbef0 /drivers/mmc/host
parent30ae3e13caeaa47884c222ebf5711ce27ed25f19 (diff)
mmc: tmio: add hook for custom busy_wait calculation
Newer SDHI variants can 'wait while busy' longer than the generic TMIO. Provide a hook to get the maximum cycle count to wait for. If the hook is not populated, fall back to a generic version which works well with all older TMIO/SDHI variants. Signed-off-by: Wolfram Sang <wsa+renesas@sang-engineering.com> Reviewed-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> Tested-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> Link: https://lore.kernel.org/r/20201125213001.15003-3-wsa+renesas@sang-engineering.com Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Diffstat (limited to 'drivers/mmc/host')
-rw-r--r--drivers/mmc/host/tmio_mmc.h1
-rw-r--r--drivers/mmc/host/tmio_mmc_core.c17
2 files changed, 13 insertions, 5 deletions
diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h
index 819198af17f4..f60559bc413a 100644
--- a/drivers/mmc/host/tmio_mmc.h
+++ b/drivers/mmc/host/tmio_mmc.h
@@ -181,6 +181,7 @@ struct tmio_mmc_host {
void (*reset)(struct tmio_mmc_host *host);
bool (*check_retune)(struct tmio_mmc_host *host);
void (*fixup_request)(struct tmio_mmc_host *host, struct mmc_request *mrq);
+ unsigned int (*get_timeout_cycles)(struct tmio_mmc_host *host);
void (*prepare_hs400_tuning)(struct tmio_mmc_host *host);
void (*hs400_downgrade)(struct tmio_mmc_host *host);
diff --git a/drivers/mmc/host/tmio_mmc_core.c b/drivers/mmc/host/tmio_mmc_core.c
index 7d2da5befe6b..942b8375179c 100644
--- a/drivers/mmc/host/tmio_mmc_core.c
+++ b/drivers/mmc/host/tmio_mmc_core.c
@@ -887,16 +887,20 @@ static void tmio_mmc_set_bus_width(struct tmio_mmc_host *host,
sd_ctrl_write16(host, CTL_SD_MEM_CARD_OPT, reg);
}
-static void tmio_mmc_max_busy_timeout(struct tmio_mmc_host *host)
+static unsigned int tmio_mmc_get_timeout_cycles(struct tmio_mmc_host *host)
{
u16 val = sd_ctrl_read16(host, CTL_SD_MEM_CARD_OPT);
- unsigned int clk_rate = host->mmc->actual_clock ?: host->mmc->f_max;
- unsigned int cycles;
val = (val & CARD_OPT_TOP_MASK) >> CARD_OPT_TOP_SHIFT;
- cycles = 1 << (13 + val);
+ return 1 << (13 + val);
+}
+
+static void tmio_mmc_max_busy_timeout(struct tmio_mmc_host *host)
+{
+ unsigned int clk_rate = host->mmc->actual_clock ?: host->mmc->f_max;
- host->mmc->max_busy_timeout = cycles / (clk_rate / MSEC_PER_SEC);
+ host->mmc->max_busy_timeout = host->get_timeout_cycles(host) /
+ (clk_rate / MSEC_PER_SEC);
}
/* Set MMC clock / power.
@@ -1116,6 +1120,9 @@ int tmio_mmc_host_probe(struct tmio_mmc_host *_host)
if (!(pdata->flags & TMIO_MMC_HAS_IDLE_WAIT))
_host->write16_hook = NULL;
+ if (pdata->flags & TMIO_MMC_USE_BUSY_TIMEOUT && !_host->get_timeout_cycles)
+ _host->get_timeout_cycles = tmio_mmc_get_timeout_cycles;
+
_host->set_pwr = pdata->set_pwr;
ret = tmio_mmc_init_ocr(_host);