diff options
author | Wolfram Sang <wsa+renesas@sang-engineering.com> | 2020-11-25 22:30:00 +0100 |
---|---|---|
committer | Ulf Hansson <ulf.hansson@linaro.org> | 2020-12-04 13:30:04 +0100 |
commit | 58959f89dd3d8cc8bedcd2d665496603098b29a2 (patch) | |
tree | 3843a3c0575b4f51f0edfee06d81362fbb2fbef0 | |
parent | 30ae3e13caeaa47884c222ebf5711ce27ed25f19 (diff) | |
download | linux-58959f89dd3d8cc8bedcd2d665496603098b29a2.tar.bz2 |
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>
-rw-r--r-- | drivers/mmc/host/tmio_mmc.h | 1 | ||||
-rw-r--r-- | drivers/mmc/host/tmio_mmc_core.c | 17 |
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); |