Message ID | 1453808801-12510-3-git-send-email-wsa@the-dreams.de (mailing list archive) |
---|---|
State | RFC |
Delegated to: | Geert Uytterhoeven |
Headers | show |
On 26.01.2016 12:46, Wolfram Sang wrote: > From: Wolfram Sang <wsa+renesas@sang-engineering.com> > > 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@sang-engineering.com> > --- > 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); I had to re-read the manual to get an idea what's special with CTL_SD_CARD_CLK_CTL so that it's done this way. Maybe we should mention this in the commit message? E.g. "Most registers except CTL_SD_CARD_CLK_CTL need to wait until ..." ? Best regards Dirk > } > > 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) > >
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)