On Wed, Dec 11, 2013 at 11:01 AM, Shawn Guo <shawn.guo@xxxxxxxxxx> wrote: > On Tue, Dec 10, 2013 at 08:56:07PM +0800, Dong Aisheng wrote: >> For host controllers using SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK, since the card >> clock is changed dynamically for different cards, it does not make sense >> to use the maximum host clock to calculate max_discard_to which may lead >> the max_discard_to to be much smaller than its capbility and affect the card >> discard performance a lot. >> e.g. the host clock is 200Mhz, but the card is working on 50Mhz. Then the >> max_discard_to is only 1/4 of its real capbility. >> >> In this patch, it uses the actual_clock to calculate the max_discard_to >> dynamically as long as a new clock speed is set. >> >> Tested with a high speed SDHC card shows: >> Originally: >> mmc1: new high speed SDHC card at address aaaa >> mmc1: calculated max. discard sectors 49152 for timeout 1355 ms >> Now: >> mmc1: new high speed SDHC card at address aaaa >> mmc1: calculated max. discard sectors 712704 for timeout 5422 ms >> The max_discard_sectors will increase a lot which will also improve discard >> performance a lot. >> >> The one known limitation of this approach is that it does not cover the special >> case for user changes the clock via sysfs, since the max_discard_to is only >> initialised for one time during the mmc queue init. >> >> Signed-off-by: Dong Aisheng <b29396@xxxxxxxxxxxxx> >> --- >> drivers/mmc/host/sdhci.c | 27 +++++++++++++++++++++------ >> 1 files changed, 21 insertions(+), 6 deletions(-) >> >> diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c >> index 4cc3bd6..9be8a79 100644 >> --- a/drivers/mmc/host/sdhci.c >> +++ b/drivers/mmc/host/sdhci.c >> @@ -1143,14 +1143,14 @@ static void sdhci_set_clock(struct sdhci_host *host, unsigned int clock) >> unsigned long timeout; >> >> if (clock && clock == host->clock) >> - return; >> + goto out; > > I do not quite understand this change. Why do we need to recalculate > max_discard_to if the clock does not change since the last time that > the function is called? > Good catch. It's safe to return directly here. Will update in v2. Regards Dong Aisheng > Shawn > >> >> host->mmc->actual_clock = 0; >> >> if (host->ops->set_clock) { >> host->ops->set_clock(host, clock); >> if (host->quirks & SDHCI_QUIRK_NONSTANDARD_CLOCK) >> - return; >> + goto out; >> } >> >> sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL); >> @@ -1249,6 +1249,19 @@ clock_set: >> >> out: >> host->clock = clock; >> + >> + /* update timeout_clk and max_discard_to once the SDCLK is changed */ >> + if (host->quirks & SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK && clock) { >> + host->timeout_clk = host->mmc->actual_clock ? >> + host->mmc->actual_clock / 1000 : >> + host->clock / 1000; >> + if (host->ops->get_max_timeout) >> + host->mmc->max_discard_to = >> + host->ops->get_max_timeout(host); >> + else >> + host->mmc->max_discard_to = (1 << 27) / >> + host->timeout_clk; >> + } >> } >> >> static inline void sdhci_update_clock(struct sdhci_host *host) >> @@ -2939,10 +2952,12 @@ int sdhci_add_host(struct sdhci_host *host) >> if (host->quirks & SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK) >> host->timeout_clk = mmc->f_max / 1000; >> >> - if (host->ops->get_max_timeout) >> - mmc->max_discard_to = host->ops->get_max_timeout(host); >> - else >> - mmc->max_discard_to = (1 << 27) / host->timeout_clk; >> + if (!(host->quirks & SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK)) { >> + if (host->ops->get_max_timeout) >> + mmc->max_discard_to = host->ops->get_max_timeout(host); >> + else >> + mmc->max_discard_to = (1 << 27) / host->timeout_clk; >> + } >> >> mmc->caps |= MMC_CAP_SDIO_IRQ | MMC_CAP_ERASE | MMC_CAP_CMD23; >> >> -- >> 1.7.2.rc3 >> >> > > > _______________________________________________ > linux-arm-kernel mailing list > linux-arm-kernel@xxxxxxxxxxxxxxxxxxx > http://lists.infradead.org/mailman/listinfo/linux-arm-kernel -- To unsubscribe from this list: send the line "unsubscribe linux-mmc" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html