OSDN Git Service

mmc: mmc: Fix mmc_partial_init for HS400 mode
authorRitesh Harjani <riteshh@codeaurora.org>
Mon, 20 Feb 2017 08:20:58 +0000 (13:50 +0530)
committerGerrit - the friendly Code Review server <code-review@localhost>
Fri, 12 May 2017 09:08:27 +0000 (02:08 -0700)
In case of emmc5.0 cards where HS400 mode and CMD5(awake) partial
init is enabled -> mmc_partial_init is broken and gives below errors.
Fix this by adding calibration logic in case of HS400 mode.

NOTE: In HS400 mode tuning is only performed once during bootup (in
HS200 mode).
Post to that it is always DLL calibration which is performed (in
system/runtime resume).
So even for below issue since timing is already changed using
cached_ios, then do the calibration using ->execute_tuning.

<dmesg errors w/o patch>
root@msm8996:/ # [   76.011036] mmc0: mmc_runtime_suspend:
[   77.315903] mmc0: mmc_runtime_resume:
[   77.367866] mmc0: mmc_partial_init: starting partial init
[   77.376225] mmc0: mmc_test_awake_ext_csd: mmc_get_ext_csd failed
(-110)
[   77.382190] mmc0: mmc_partial_init: done partial init (-110)
[   77.387536] mmc0: _mmc_resume: awake failed (-110), fallback to full
init
[   77.394405] mmc0: mmc_init_card:
[   77.402762] mmc0: mmc_init_card: mmc_send_op_cond() fails -110
[   77.407573] mmc0: MMC card re-init failed rc = -110 (retries = 3)
[   77.507261] mmc0: _mmc_resume: awake failed (-110), fallback to full
init
[   77.513293] mmc0: mmc_init_card:

<dmesg with patch>
[   74.002624] mmc0: mmc_runtime_resume:
[   74.056089] mmc0: mmc_partial_init: starting partial init
[   74.067143] mmc0: mmc_partial_init: done partial init (0)

Change-Id: I0e55efb7863b75bd584843c3fc920c845996eb5c
Signed-off-by: Ritesh Harjani <riteshh@codeaurora.org>
drivers/mmc/core/mmc.c

index 6912871..5eda4f4 100644 (file)
@@ -2617,6 +2617,9 @@ static int mmc_partial_init(struct mmc_host *host)
        if (mmc_card_hs400(card)) {
                if (card->ext_csd.strobe_support && host->ops->enhanced_strobe)
                        err = host->ops->enhanced_strobe(host);
+               else if (host->ops->execute_tuning)
+                       err = host->ops->execute_tuning(host,
+                               MMC_SEND_TUNING_BLOCK_HS200);
        } else if (mmc_card_hs200(card) && host->ops->execute_tuning) {
                err = host->ops->execute_tuning(host,
                        MMC_SEND_TUNING_BLOCK_HS200);