From: Wolfram Sang <wsa+renesas@xxxxxxxxxxxxxxxxxxxx> Most registers need to wait until the command is completed, not necessarily until the bus is free. RCar SoCs can signal that via the CBSY bit, so let's use it instead of SCLKDIVEN to save a few ns of delay. Signed-off-by: Wolfram Sang <wsa+renesas@xxxxxxxxxxxxxxxxxxxx> --- drivers/mmc/host/sh_mobile_sdhi.c | 15 +++++++++++---- include/linux/mmc/tmio.h | 3 +++ 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/drivers/mmc/host/sh_mobile_sdhi.c b/drivers/mmc/host/sh_mobile_sdhi.c index 12419acb8ac9f5..dd08e945b2d3dd 100644 --- a/drivers/mmc/host/sh_mobile_sdhi.c +++ b/drivers/mmc/host/sh_mobile_sdhi.c @@ -156,11 +156,13 @@ static void sh_mobile_sdhi_clk_disable(struct platform_device *pdev) clk_disable_unprepare(priv->clk); } -static int sh_mobile_sdhi_wait_idle(struct tmio_mmc_host *host) +static int sh_mobile_sdhi_wait_idle(struct tmio_mmc_host *host, u16 bit) { int timeout = 1000; + /* CBSY is set when busy, SCLKDIVEN is cleared when busy */ + u16 wait_state = (bit == STATUS2_CBSY ? STATUS2_CBSY : 0); - while (--timeout && !(sd_ctrl_read16(host, CTL_STATUS2) & (1 << 13))) + while (--timeout && (sd_ctrl_read16(host, CTL_STATUS2) & bit) == wait_state) udelay(1); if (!timeout) { @@ -173,18 +175,23 @@ static int sh_mobile_sdhi_wait_idle(struct tmio_mmc_host *host) static int sh_mobile_sdhi_write16_hook(struct tmio_mmc_host *host, int addr) { + u16 bit = STATUS2_SCLKDIVEN; + switch (addr) { case CTL_SD_CMD: case CTL_STOP_INTERNAL_ACTION: case CTL_XFER_BLK_COUNT: - case CTL_SD_CARD_CLK_CTL: case CTL_SD_XFER_LEN: case CTL_SD_MEM_CARD_OPT: case CTL_TRANSACTION_CTL: case CTL_DMA_ENABLE: case EXT_ACC: - return sh_mobile_sdhi_wait_idle(host); + if (host->pdata->flags & TMIO_MMC_IS_RCAR) + bit = STATUS2_CBSY; + /* fallthrough */ + case CTL_SD_CARD_CLK_CTL: + return sh_mobile_sdhi_wait_idle(host, bit); } return 0; diff --git a/include/linux/mmc/tmio.h b/include/linux/mmc/tmio.h index 5f5cd80e976500..6ae480d6fec891 100644 --- a/include/linux/mmc/tmio.h +++ b/include/linux/mmc/tmio.h @@ -63,6 +63,9 @@ #define TMIO_STAT_CMD_BUSY 0x40000000 #define TMIO_STAT_ILL_ACCESS 0x80000000 +#define STATUS2_CBSY BIT(14) /* only known on RCar */ +#define STATUS2_SCLKDIVEN BIT(13) + #define CLK_CTL_DIV_MASK 0xff #define CLK_CTL_SCLKEN BIT(8) -- 2.1.4