[PATCH 5/6] mmc: sdhci: calculate max_discard_to dynamically for SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK
Dong Aisheng
dongas86 at gmail.com
Tue Dec 10 22:13:38 EST 2013
On Wed, Dec 11, 2013 at 11:01 AM, Shawn Guo <shawn.guo at linaro.org> 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 at freescale.com>
>> ---
>> 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 at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
More information about the linux-arm-kernel
mailing list